From 50d2baf469d31c9b443aec05f8a080ed53881a32 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Thu, 3 Mar 2022 13:34:46 +0100 Subject: [PATCH 1/8] Tweaks to the upgrade guide. Minor changes to language/readability and an extra note about migrating webpack configuration before deleting --- UPGRADING.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 84a2b2a..7011081 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,7 +2,7 @@ Propshaft has a smaller scope than Sprockets, therefore migrating to it will also require you to adopt the [jsbundling-rails](https://github.com/rails/jsbundling-rails) and [cssbundling-rails](https://github.com/rails/cssbundling-rails) gems. This guide will assume your project follows Rails 6.1 conventions of using [webpacker](https://github.com/rails/webpacker) to bundle javascript, [sass-rails](https://github.com/rails/sass-rails) to bundle css and [sprockets](https://github.com/rails/sprockets) to digest assets. Finally, you will also need [npx](https://docs.npmjs.com/cli/v7/commands/npx) version 7.1.0 or later installed. -## 1. Migrate from webpacker to jsbundling-rails +## 1. Migrate from Webpacker to jsbundling-rails Start by following these steps: @@ -12,20 +12,20 @@ Start by following these steps: 4. Remove the file `config/initializers/assets.rb`; 5. Remove the file `bin/webpack`; 5. Remove the file `bin/webpack-dev-server`; -6. Remove the folder `config/webpack`; +6. Remove the folder `config/webpack` (note: any custom configuration should be migrated to the new `webpack.config.js` file); 7. Replace all instances of `javascript_pack_tag` with `javascript_include_tag` and add `defer: true` to them. After you are done you will notice that the install step added various files to your project and updated some of the existing ones. **The new 'bin/dev' and 'Procfile.dev' files** -The `./bin/dev` file is a shell script that uses [foreman](https://github.com/ddollar/foreman) and `Procfile.dev` to start two processes in a single terminal: `rails s` and `yarn build`. The latter replaces `webpack-dev-server` in bundling and watching for changes in javascript files. +The `./bin/dev` file is a shell script that uses [foreman](https://github.com/ddollar/foreman) and `Procfile.dev` to start two processes in a single terminal: `rails s` and `yarn build`. The latter replaces `webpack-dev-server` for bundling and watching for changes in javascript files. **The 'build' attribute added to packages.json** This is the command that `yarn build` will use to bundle javascript files. -**The new 'webpack.config.js file'** +**The new 'webpack.config.js' file** In `webpacker` this file was hidden inside the gem, but now you can edit it directly. If you had custom configuration in `config/webpack` you can move them to here. Projects with multiple entrypoints will need to adjust the `entry` attribute: @@ -141,7 +141,7 @@ Start by following these steps: **Asset paths** -Propshaft will automatically include in its search paths the folders `vendor/assets`, `lib/assets` and `app/assets` of your project and all the gems in your gemfile. You can see all included files by using the `reveal` rake task: +Propshaft will automatically include in its search paths the folders `vendor/assets`, `lib/assets` and `app/assets` of your project and of all the gems in your Gemfile. You can see all included files by using the `reveal` rake task: ``` rake assets:reveal ``` @@ -170,7 +170,7 @@ background: image_url('hero.jpg') Using the same path with `url` in Propshaft will cause it to raise an error, saying it cannot locate `theme/hero.jpg`. That's because Propshaft assumes all paths are relative to the path of the file it's processing. Since it was processing a css file inside the `theme` folder, it will also look for `hero.jpg` in the same folder. -By adding a `/` at the start of the path we are telling Propshaft to consider to treat this path as an absolute path. While this change in behavior increases the work a bit when upgrading, it makes **external libraries like FontAwesome and Bootstrap themes work out-of-the-box**. +By adding a `/` at the start of the path we are telling Propshaft to consider this path as an absolute path. While this change in behavior increases the work a bit when upgrading, it makes **external libraries like FontAwesome and Bootstrap themes work out-of-the-box**. **Asset content** @@ -181,4 +181,4 @@ Rails.application.assets.load_path.find('logo.svg').content **Precompilation in development** -Propshaft is using dynamic assets resolver in development mode. However, when you run `assets:precompile` locally - it's then switching to static assets resolver. Your changes to assets will not be anymore observed and you'd have to precompile assets each time. This is different to Sprockets. +Propshaft uses a dynamic assets resolver in development mode. However, when you run `assets:precompile` locally Propshaft will then switch to a static assets resolver. Therefore, changes to assets will not be observed anymore and you will have to precompile the assets each time changes are made. This is different to Sprockets. From a80f1b49db94ac4d1b154ce2625f9780d4603730 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Thu, 3 Mar 2022 16:56:24 +0100 Subject: [PATCH 2/8] We can also remove config/webpacker.yml --- UPGRADING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 7011081..4d6a4ee 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -11,9 +11,10 @@ Start by following these steps: 3. Run `./bin/rails javascript:install:webpack`; 4. Remove the file `config/initializers/assets.rb`; 5. Remove the file `bin/webpack`; -5. Remove the file `bin/webpack-dev-server`; -6. Remove the folder `config/webpack` (note: any custom configuration should be migrated to the new `webpack.config.js` file); -7. Replace all instances of `javascript_pack_tag` with `javascript_include_tag` and add `defer: true` to them. +6. Remove the file `bin/webpack-dev-server`; +7. Remove the folder `config/webpack` (note: any custom configuration should be migrated to the new `webpack.config.js` file); +8. Remove the file `config/webpacker.yml`; +9. Replace all instances of `javascript_pack_tag` with `javascript_include_tag` and add `defer: true` to them. After you are done you will notice that the install step added various files to your project and updated some of the existing ones. From 35547373fb3594ad3688fe565eac8e56e60198b9 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 12:12:35 +0100 Subject: [PATCH 3/8] Note about module resolution after migrating from webpacker --- UPGRADING.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index 4d6a4ee..3500bef 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -72,6 +72,22 @@ Then open `packages.json` and add this: Finally, download [webpackers babel preset](https://github.com/rails/webpacker/blob/master/package/babel/preset.js) file and place it in the same directory as `packages.json` with the name `webpack.babel.js`. +**Module resolution** + +Webpacker included the the `source_path` into module resolution, so statements like `import 'channels'` imported`app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behaviour: + +```javascript +module.exports = { + // ... + resolve: { + modules: ["app/javascript", "node_modules"], + }, + //... +} +``` + +Alternatively you can change to relative imports for those modules. + ## 2. Migrate from sass-rails to cssbundling-rails Start by following these steps: From bcf60f37127899200186efbf6f936e964ce3fc06 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 12:35:59 +0100 Subject: [PATCH 4/8] Add section about migrating `extract_css` option --- UPGRADING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index 3500bef..2095c6b 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -86,6 +86,53 @@ module.exports = { } ``` +**Extracting Sass/SCSS from JavaScript** + +In webpacker it is possible to extract Sass/SCSS from JavaScript by enabling `extract_css` in `webpacker.yml`. This allows for including those source files in JavaScript, e.g. `import '../scss/application.scss` + +If you wish to keep this functionality follow these steps: + +1. Run `yarn add mini-css-extract-plugin sass sass-loader css-loader`; +2. Update your `webpack.config.js` to require `mini-css-extract-plugin` and configure the loaders (see example below). + +Example `webpack.config.js`: + +```javascript +const path = require("path") +const webpack = require("webpack") +const MiniCssExtractPlugin = require("mini-css-extract-plugin") + +module.exports = { + mode: "production", + devtool: "source-map", + entry: { + application: "./app/javascript/application.js" + }, + resolve: { + modules: ["app/javascript", "node_modules"], + }, + output: { + filename: "[name].js", + sourceMapFilename: "[file].map", + path: path.resolve(__dirname, "app/assets/builds"), + }, + plugins: [ + new MiniCssExtractPlugin(), + new webpack.optimize.LimitChunkCountPlugin({ + maxChunks: 1 + }) + ], + module: { + rules: [ + { + test: /\.s[ac]ss$/i, + use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], + }, + ], + }, +} +``` + Alternatively you can change to relative imports for those modules. ## 2. Migrate from sass-rails to cssbundling-rails From e5fa4bb950687d05583cd1e46199eba901bd851a Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 12:51:33 +0100 Subject: [PATCH 5/8] Add note about if CSS was only built via webpacker extract_css --- UPGRADING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index 2095c6b..c2cd488 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -137,6 +137,8 @@ Alternatively you can change to relative imports for those modules. ## 2. Migrate from sass-rails to cssbundling-rails +Note: if your application used Webpacker's `extract_css` to build your CSS and did not require `sass-rails`, you can skip this section. + Start by following these steps: 1. Add `cssbundling-rails` to your Gemfile; From 8d25c88d0755c2fb78fdfdf272bd9c8d30d4c3cd Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 12:58:49 +0100 Subject: [PATCH 6/8] Clarify that propshaft depends on Rails 7 --- UPGRADING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index c2cd488..492b78c 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,6 +2,8 @@ Propshaft has a smaller scope than Sprockets, therefore migrating to it will also require you to adopt the [jsbundling-rails](https://github.com/rails/jsbundling-rails) and [cssbundling-rails](https://github.com/rails/cssbundling-rails) gems. This guide will assume your project follows Rails 6.1 conventions of using [webpacker](https://github.com/rails/webpacker) to bundle javascript, [sass-rails](https://github.com/rails/sass-rails) to bundle css and [sprockets](https://github.com/rails/sprockets) to digest assets. Finally, you will also need [npx](https://docs.npmjs.com/cli/v7/commands/npx) version 7.1.0 or later installed. +Propshaft depends on Rails 7, so you will need to upgrade to Rails 7+ before starting the migration. + ## 1. Migrate from Webpacker to jsbundling-rails Start by following these steps: From e8d11289c93914af5fb678267b0e9852a222b9c1 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 16:50:30 +0100 Subject: [PATCH 7/8] Fixes to document updates about module resolution after migration --- UPGRADING.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 492b78c..a5e8df5 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -76,7 +76,7 @@ Finally, download [webpackers babel preset](https://github.com/rails/webpacker/b **Module resolution** -Webpacker included the the `source_path` into module resolution, so statements like `import 'channels'` imported`app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behaviour: +Webpacker included the `source_path` (default: `app/javascript/`) into module resolution, so a statement like `import 'channels'` imported `app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behaviour: ```javascript module.exports = { @@ -88,6 +88,12 @@ module.exports = { } ``` +Alternatively, you can change modules to use relative imports, for example: +```diff +- import 'channels' ++ import './channels' +``` + **Extracting Sass/SCSS from JavaScript** In webpacker it is possible to extract Sass/SCSS from JavaScript by enabling `extract_css` in `webpacker.yml`. This allows for including those source files in JavaScript, e.g. `import '../scss/application.scss` @@ -135,8 +141,6 @@ module.exports = { } ``` -Alternatively you can change to relative imports for those modules. - ## 2. Migrate from sass-rails to cssbundling-rails Note: if your application used Webpacker's `extract_css` to build your CSS and did not require `sass-rails`, you can skip this section. From 63087b9a3dfddf9121f78786cbcb5c47c14e0f74 Mon Sep 17 00:00:00 2001 From: Stephen Ierodiaconou Date: Fri, 4 Mar 2022 16:55:48 +0100 Subject: [PATCH 8/8] Favor US spelling on upgrading doc --- UPGRADING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADING.md b/UPGRADING.md index a5e8df5..2867afd 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -76,7 +76,7 @@ Finally, download [webpackers babel preset](https://github.com/rails/webpacker/b **Module resolution** -Webpacker included the `source_path` (default: `app/javascript/`) into module resolution, so a statement like `import 'channels'` imported `app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behaviour: +Webpacker included the `source_path` (default: `app/javascript/`) into module resolution, so a statement like `import 'channels'` imported `app/javascript/channels/`. After migrating to `jsbundling-rails` this is no longer the case. You will need to update your `webpack.config.js` to include the following if you wish to maintain that behavior: ```javascript module.exports = {