Importing js libs in files outside of main app.js

Hi,

Apologies in advance that this might be a JS or webpack question, and not Phoenix related, but I just can’t get my head around the default/basic settings of webpack provided by Phoenix.

My problem is trying to import a library (BulmaJS) within a js file other than app.js.

In app.js, this works fine:

import  Bulma from '@vizuaalog/bulmajs';

and Bulma is available anywhere in this app.js file.
I want to run Bulma functions later in a dynamic fashion, and have an HTML template which loads a custom.js file as such:

In custom.html.eex, I load the custom.js script:

<div>some html tags here... </div>
<script type="text/javascript" src="/js/custom.js">

The custom.js loads fine, however, as app.js gets loaded after the template is rendered in app.html.eex, Bulma is not available. So, I would like to put import Bulma from '@vizuaalog/bulmajs'; in the custom.js file but this just returns an Unexpected identifier error message. Why is this?

In webpack.config.js, I have tried both entry points settings to no avail:

module.exports = (env, options) => ({
  optimization: {
    minimizer: [
      new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
      new OptimizeCSSAssetsPlugin({})
    ]
  },
  entry: {
    app: './js/app.js',
    custom: '/js/custom.js'
  },

and just entry: './js/app.js',

I also tried to make Bulma available using the Webpack.providePlugin, but access to Bulma stays undefined (is that because it gets output to app.js and is only loaded after custom.html.eex template is rendered with the custom.js script?

plugins: [
    new MiniCssExtractPlugin({ filename: '../css/app.css' }),
    new CopyWebpackPlugin([{ from: 'static/', to: '../' }]),
    new Webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Bulma: 'Bulma'
    }
)]

Any hints will be most appreciated, thanks.

1 Like

You need to add custom.js as an entry point so webpack can do its thing on it (so you can use import Bulma from '@vizuaalog/bulmajs'; inside it).

So this is correct:

  entry: {
    app: './js/app.js',
    custom: '/js/custom.js'
  },

but the part where you use it:

<script type="text/javascript" src="/js/custom.js">

needs to be changed to point to webpack’s output (instead of the source file)

If it is webpack in dev server mode, then it would be something like http://localhost:8080/custom.js
For published for production it would also need to point to something different rather than the source file, depending on webpack settings.

You could maybe view the source of the file that uses the app.js script to see what the url should look like.

At this point I would recommend maybe setting entry part to:

  entry: {
    app: './js/app.js',
    mytest: '/js/custom.js'
  },

ie. make it a different name rather than custom so you don’t get confused between source and output url.

Then it might be used with:

<script type="text/javascript" src="http://localhost:8080/mytest.js">

(This is just a guess cause it depends on webpack config.)

4 Likes

Thanks!
I created another entry point with a different name between from source as you said, and all works!

1 Like

I had to restart my server (to rerun webpacker) in order for the changes to update.