pedromvieira
Phoenix 1.3 to 1.4 - Migrating from Brunch to Webpack
Do you recommend any fast guide to migrate brunch (Phoenix 1.3) to webpack (Phoenix 1.4)? Including globals, css, the whole nine yards.
At least to me, this is a huge burden in migration right now.
Can we still use brunch in Phoenix 1.4?
Marked As Solved
pedromvieira
I just confirmed that we can still use the same BRUNCH from previous (<= 1.3) inside Phoenix 1.4.
Other than correct “Routes.my_path” shortcut mentioned in README, we need also to comment in dev.exs watcher:
config :myapp, MyAppWeb.Endpoint,
debug_errors: true,
code_reloader: true,
check_origin: false,
watchers: [
# node: [
# "node_modules/webpack/bin/webpack.js",
# "--mode",
# "development",
# "--watch-stdin",
# cd: Path.expand("../assets", __DIR__)
# ]
node: [
"node_modules/brunch/bin/brunch", "watch", "--stdin",
cd: Path.expand("../assets", __DIR__)
]
]
Also Liked
dbern
I agree with @hubertlepicki you can stay on Brunch and just focus on one upgrade at a time.
If you want to jump to webpack with SCSS support, then here’s where I landed in my webpack config below. This isn’t a fast guide, but you can use below as a point of comparison.
const path = require('path')
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')
const devMode = process.env.NODE_ENV !== 'production'
module.exports = (env, options) => ({
optimization: {
minimizer: [
new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: devMode }),
new OptimizeCSSAssetsPlugin({})
]
},
entry: {
app: ['./js/app.js', './scss/app.scss']
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js')
},
devtool: devMode ? 'source-map' : undefined,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.(scss|sass|css)$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
sourceMap: devMode
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: devMode
}
},
{
loader: 'sass-loader',
options: {
sourceMap: devMode
}
},
{
loader: 'import-glob-loader'
}
]
},
{
test: /\.svg$/,
oneOf: [
{
use: {
loader: 'svg-inline-loader',
options: {
removeSVGTagAttrs: false
}
},
issuer: [{ not: [{ test: /\.css$/i }] }]
},
{
use: {
loader: 'file-loader'
},
issuer: [{ test: /\.css$/i }]
}
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: '../fonts'
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({ filename: '../css/[name].css' }),
new CopyWebpackPlugin([{ from: 'static/', to: '../' }])
]
})
This is in the ./assets/.babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": "Firefox ESR, Chrome >= 49, Safari >= 10, iOS >= 10, last 1 version"
},
"useBuiltIns": "entry"
}
]
],
"plugins": []
}
This is in the package.json:
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"babel-eslint": "^9.0.0",
"babel-loader": "^8.0.0",
"copy-webpack-plugin": "^4.5.0",
"css-loader": "^0.28.10",
"eslint": "^5.4.0",
"eslint-plugin-jsx-a11y": "^6.1.1",
"eslint-plugin-prettier": "^2.6.2",
"eslint-plugin-react": "^7.11.1",
"file-loader": "^2.0.0",
"import-glob-loader": "^1.1.0",
"mini-css-extract-plugin": "^0.4.0",
"node-sass": "^4.9.3",
"optimize-css-assets-webpack-plugin": "^4.0.0",
"postcss-import": "^12.0.0",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.0.10",
"prettier": "^1.14.2",
"sass-loader": "^7.1.0",
"svg-inline-loader": "^0.8.0",
"uglifyjs-webpack-plugin": "^1.2.4",
"webpack": "4.4.0",
"webpack-cli": "^2.0.10"
},
then in app.html.eex
<!-- within <head> -->
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
<!-- at the bottom of <body> -->
<script async type="text/javascript" src="<%= Routes.static_path(@conn, "/js/vendor.js") %>"></script>
This supports SVGs, fonts, SCSS/SASS, and modern JavaScript.
This config above includes PostCSS and Node SASS, but the way most people actually use SCSS should be mostly compatible with PostCSS. In my project, I can actually get away with dropping node-sass and the sass-loader, renaming my *.scss files to *.css, and compile faster.
I don’t have any globals, so I can’t provide a comparison there, but it looks like you’ll want the ProvidePlugin | webpack
Hopefully that helps.
pedromvieira
I will try to use Brunch with Phoenix 1.4 and will post here.
The ideia is something like this. (Copy files…)
BRUNCH
plugins: {
copycat: {
"fonts": [
"node_modules/notosans-fontface/fonts",
"node_modules/grapesjs/dist/fonts"
],
"flags": [
"node_modules/flag-icon-css/flags"
]
}
},
WEBPACK
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = (env, options) =>; ({
plugins: [
new CopyWebpackPlugin([
{ from: 'static/', to: '../' },
{ from: 'node_modules/notosans-fontface/fonts', to: '../fonts' },
{ from: 'node_modules/flag-icon-css/flags', to: '../flags' }
]),
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










