Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Add CSS/JS Dependencies To Phoenix Project?

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.

like image 691
Emily Avatar asked Dec 26 '15 10:12

Emily


3 Answers

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!

like image 110
José Valim Avatar answered Nov 16 '22 13:11

José Valim


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.

like image 22
denis.peplin Avatar answered Nov 16 '22 12:11

denis.peplin


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.

like image 4
Dmitry Biletskyy Avatar answered Nov 16 '22 14:11

Dmitry Biletskyy