11

I'm trying to add jquery to a Phoenix project.

When I link to jquery direct in app.html.eex in the head tag like so:

<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

...It works.

However, I don't want a web dependency. I want jquery within the app.

I've copied jquery.min.js to the web/static/js directory. And referenced it in app.html.eex like so:

<script src="<%= static_path(@conn, "/js/jquery.min.js") %>"></script>

It doesn't work.

Copying jquery.min.js to app.js doesn't work either.

Interesting enough when I place the JS between script tags directly in app.html.eex, it works.

Only a direct link from the cloud and/or placing the JS between a script tag in app.html.eex is working??

Update:

Brunch is copying the JS to app.js in the priv directory. But the application doesn't seem to have access to it.

What am I doing wrong.

IgorekPotworek
  • 1,317
  • 13
  • 33
Emily
  • 2,129
  • 3
  • 18
  • 43

4 Answers4

17

We recommend you to put vendor dependencies inside "web/static/vendor" because those dependencies are often not in ES6 nor work with JS loaders. Also, when you add them to vendor, they will be automatically added to the built app.js by brunch.

Alternatively, you can follow Dmitry's feedback. In this case, you can place the file inside "web/static/assets" and it will be copied as is to your application. For example, by putting it at "web/static/assets/js/jquery-min.js", the script tag you have defined in your post should work.

Update

After studying the sample repository given in the comments, the bug seems to be in the ordering: bootstrap is being included in the app.js file before jquery. You can fix this by adding the following to your brunch-config.js (a similar sample is already commented in there):

  order: {
    before: [
      "web/static/vendor/js/jquery.min.js",
      "web/static/vendor/js/bootstrap-toggle.min.js"
    ]
  }

I have to agree this is not obvious. Alternative solutions:

  1. Order them in your vendor directory, for example: 1_jquery.min.js, 2_bootstrap-toggle.min.js, etc.

  2. Move the files to "web/static/assets/js/jquery-min.js" and so on and add explicit script tags for them in your pages

I hope this helps!

José Valim
  • 50,409
  • 12
  • 130
  • 115
  • Thanks. I must be missing something somewhere though. I've added the js to the vendor folder. Then run node node_modules/brunch/bin/brunch build. The js shows compiled in priv/static/js, yet it doesn't seem to work in the app. However direct web links to the js in app.html.eex do work. What might cause this? Any ideas for a fix? – Emily Dec 26 '15 at 12:31
  • Do you have an application on GitHub that shows the issue? I would gladly take a look. :) – José Valim Dec 29 '15 at 11:24
  • To be clear, if you are using vendor, you still need this line in your layout: `` – José Valim Dec 29 '15 at 11:25
  • Big thanks. Heres the github: http://github.com/makeitgreat/phoenix_a_b_test If you navigate to: localhost:4000/test_a.html & localhost:4000/test_b.html you can see the bug. test_b.html.eex has the external css & JS links. test_a.html.eex doesn’t. JS & CSS show in priv directory app.js & app.css – Emily Dec 29 '15 at 15:56
  • Ok, I solved it. It was an ordering issue! I have updated the answer. – José Valim Dec 31 '15 at 07:37
  • Hi, I am very new to phoenix(as today is my second day) I want to add jquery.js library to my application and I followed above steps and I still get $ is not defined.... I even cloned the above github-link ( github.com/makeitgreat/phoenix_a_b_test and still getting same error... Please help me with this part as I already lost 2 days to figure out – KJ_kaka Dec 31 '15 at 13:45
  • @KJ_kaka if you build a new phoenix application and just drop jquery (nothing more) inside web/static/vendor/js, it should just work. If you are dropping other dependencies that depend on js, you may need to order them in your brunch-config.js file. Also, make sure that when you run `mix phoenix.server` there are no warnings or errors in the terminal. If there are, please open up a new question with them. :) – José Valim Dec 31 '15 at 15:38
  • @JoseValim I followed these steps. 1) mix phoenix.new inceptionApp --database mysql, 2) cd inceptionApp/, 3) gave username credentials ,4) mix ecto.create 5)mix ecto.migrate and then downloaded jquery.js file and placed it in this folder web/static/vendor/js and then I started server 6)mix phoenix.server and still i get same error 'Uncaught ReferenceError: $ is not defined' and here is my repo https://github.com/vikasd02/incApp – KJ_kaka Jan 01 '16 at 18:48
  • You have two jquery entries web/static/vendor/js in there. Why? – José Valim Jan 03 '16 at 08:53
12

While copying libraries to static works, I don't like it at all, because it trashes git log a lot for every update of every JS library, especially a big one.

Fortunately, Phoenix has official support for adding JS libs via npm/Brunch and it is present in the documentation: Static Assets - Javascript Libraries.

This is how I've added jQuery into my application:

NOTE: This is for Phoenix 1.3, see instructions for 1.4 below

Added jquery with a version number to dependencies section of package.json:

{
  ...
  "dependencies": {
    ...
    "jquery": "3.2.1"
  }
}

Performed install:

npm install --save

Added globals into npm section of brunch-config.js:

npm: {
  enabled: true,
  globals: {
    $: 'jquery',
    jQuery: 'jquery'
  }
}

After app restart, I was able to use $.

UPDATE for Phoenix 1.4

Phoenix 1.4 switched from Brunch to Webpack.

assets/package.json

{
  ...
  "dependencies": {
    ...
    "jquery": "3.3.1"
  }
}

assets/webpack.config.js

const webpack = require('webpack');
...
  plugins: [
  ...
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    })
  ]

assets/js/app.js (this one is optional, but is required to make $ available in Chrome console)

window.$ = window.jQuery = require("jquery");

Run

(cd assets && npm install)

and restart Phoenix application.

denis.peplin
  • 9,585
  • 3
  • 48
  • 55
4

Dependencies in Phoenix are managed by Brunch.io. By default it copies everything from /web/static/assets/ directory to /priv/static.

So you can simply create some directory like plugins inside /web/static/assets/ and copy jquery.min.js there.

Dmytro Biletskyi
  • 1,833
  • 15
  • 21
0

I don't have enough reputation to post a comment to the answer from @denis.peplin (in which the link is outdated). But it seems this is the official post referred to (again there is a Javascript Libraries section)...

phoenixframework-blog-static-assets

In my case the following worked:

Add the dependency to package.json

"dependencies": {
  "jquery": "3.2.1"
},

Then in assets/js/app.js add the following line...

import $ from "jquery"