Owens

Owens

How Webpack 4 works with Phoenix 1.4

Hello all, I want to understand better how Webpack works with Phoenix 1.4.

I’ve seen conflicting implementations on Github, so would be great to clarify how it interacts with Phoenix.

Here’s the default Webpack.config.js

    const path = require('path');
    const glob = require('glob');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
    const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const CopyWebpackPlugin = require('copy-webpack-plugin');

    module.exports = (env, options) => ({
      optimization: {
        minimizer: [
          new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: false }),
          new OptimizeCSSAssetsPlugin({})
        ]
      },
      entry: {
          './js/app.js': ['./js/app.js'].concat(glob.sync('./vendor/**/*.js'))
      },
      output: {
        filename: 'app.js',
        path: path.resolve(__dirname, '../priv/static/js')
      },
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: 'babel-loader'
            }
          },
          {
            test: /\.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader']
          }
        ]
      },
      plugins: [
        new MiniCssExtractPlugin({ filename: '../css/app.css' }),
        new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
      ]
    });

One thing big thing I noticed is that this config does not specify the mode (ie. development or production). Therefore it will default to production according to the Webpack docs.

Is this on purpose? If so, why?

More specifically, how does this impact what packages should be added as DevDependencies vs general dependencies in Webpack?

In setting up Bootstrap 4, here’s how I set up my dependencies in Webpack:

    {
      "repository": {},
      "license": "MIT",
      "scripts": {
        "deploy": "webpack --mode production",
        "watch": "webpack --mode development --watch"
      },
      "dependencies": {
        "autoprefixer": "^9.3.1",
        "bootstrap": "^4.1.3",
        "coffeescript": "^2.3.2",
        "jquery": "^3.3.1",
        "node-sass": "^4.10.0",
        "phoenix": "file:../deps/phoenix",
        "phoenix_html": "file:../deps/phoenix_html",
        "popper.js": "^1.14.5",
        "postcss-loader": "^3.0.0",
        "sass-loader": "^7.1.0"
      },
      "devDependencies": {
        "@babel/core": "^7.0.0",
        "@babel/preset-env": "^7.0.0",
        "babel-loader": "^8.0.0",
        "copy-webpack-plugin": "^4.5.0",
        "css-loader": "^0.28.10",
        "mini-css-extract-plugin": "^0.4.0",
        "optimize-css-assets-webpack-plugin": "^4.0.0",
        "uglifyjs-webpack-plugin": "^1.2.4",
        "webpack": "4.4.0",
        "webpack-cli": "^2.0.10"
      }
    }

Basically, I added everything as dependencies and nothing as DevDependencies. Is this right? My hunch is no. My hunch is that everything should be a DevDependency, as Webpack will compile the assets and Phoenix will then compile the app.

My hunch is that the only two dependencies should be Phoenix and Phoenix_html. Even Jquery should be a DevDependency (or should it just be installed in node_modules and then just imported in Phoenix’s App.js without listing it as a dependency?).

So many potential conflicts here.

Would be great to get more insight into this!

Marked As Solved

theangryangel

theangryangel

The mode is specified in the arguments for the watcher in config/dev.exs

No. You ideally want anything related to building in your devDependencies. I.e. your node-sass, autoprefixer, etc. should ideally be in devdeps. JQuery is a runtime dependent on your web app (I.e it’s not compiled away) so it should be a regular dep imho.

Erm. No.

You want running npm install to get all your deps. With them not in your package.json that’s not gonna work when you install on a new dev machine or VM, and they won’t be present in your node_modules

I think you should read the getting started of webpack and nodejs package management. It may help.

Also Liked

theangryangel

theangryangel

These are 2 different things…

The package.json describes where to get and how to install jquery, bootstrap, etc. from npm. If you’ve got the files in your assets directory outside of node_modules then it’s not required in your package.json.

The import in your app.js and app.scss brings files into your project from either node modules (npm, etc.), or other files in your assets.

Owens

Owens

Thanks for the reply!

Tell me if this looks right:

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "webpack --mode production",
    "watch": "webpack --mode development --watch"
  },
  "dependencies": {
    "bootstrap": "^4.1.3",
    "jquery": "^3.3.1",
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html",
    "popper.js": "^1.14.5",
  },
  "devDependencies": {
    "autoprefixer": "^9.3.1",
    "coffeescript": "^2.3.2",
    "@babel/core": "^7.0.0",
    "@babel/preset-env": "^7.0.0",
    "babel-loader": "^8.0.0",
    "copy-webpack-plugin": "^4.5.0",
    "css-loader": "^0.28.10",
    "mini-css-extract-plugin": "^0.4.0",
    "node-sass": "^4.10.0",
    "optimize-css-assets-webpack-plugin": "^4.0.0",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "uglifyjs-webpack-plugin": "^1.2.4",
    "webpack": "4.4.0",
    "webpack-cli": "^2.0.10"
  }
}

I added all the loaders and coffeescript to the DevDependencies.

I’m still wondering why we need to have Bootstrap, Jquery, and Popper.js, in the dependencies list if they are imported manually inside app.sass and app.js. If I am understanding this right, Webpack or Nodejs is the mechanism by which they are imported into the app.sass and app.js? So if they are not listed in dependencies then they won’t be found?

Thanks again.

Where Next?

Popular in Questions Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43806 214
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31307 143
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New

We're in Beta

About us Mission Statement