common-chunks-manifestjson-including-css-from-a-node-module
Common Chunks, Manifest.json, Including css from a node module​
Common Chunks Plugin
The idea is to create a chunk of all the modules, helpers, and such js/css files which are used in multiple places (>4) like in all apps. This is done so that we only compile the commonly used helper once instead of compiling it for every single file it is used in. Webpack compiling quicker => faster development => faster deploys
One giant common chunk vs multiple small ones Con: This is what we had before. The problem with that is that was that we were loading extra js on pages that id not need it. Like the view page was loading react and other libraries that are never used there. Pro: We make a single request to get all the js.
Read more about it here: https://webpack.js.org/plugins/commons-chunk-plugin/
Our current chunk strategy: Chunk all helpers which are used in 4 or more files except React and some other modules which are used on plugin setting pages only. Snippet from webpack settings
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'base-settings-and-react-components',
minChunks: 4
}),
new webpack.optimize.CommonsChunkPlugin({
name: "commons",
minChunks: function(module){
return module.context && (
!module.context.includes("modules/settings") &&
!module.context.includes("react") &&
!module.context.includes("tinymce")
);
}
}),
],
Manifest.json
Once you run the webpack compiler - ./bin/webpack-dev-server auto run by foreman - it will generate a manifest.json (public/assets/packs/manifest.json) which will have these new files and the routes to them along with your other files.
"app-settings-specific.css": "https://localhost:3002/assets/packs/base-settings-and-react-components.css",
"app-settings-specific.js": "https://localhost:3002/assets/packs/base-settings-and-react-components.js",
"commons.js": "https://localhost:3002/assets/packs/commons.js"
Note: There is no physical file you can search in your codebase by name base-settings-and-react-components.js but you can see it's contents by visiting the url ( "https://localhost:3002/assets/packs/base-settings-and-react-components.js") listed next to it.
Including common chunk
Example of how we include js https://github.com/superpowr/powr/blob/master/app/views/layouts/application.html.haml#L76
= javascript_pack_tag "commons"
- if content_for?(:webpack_js_chunk)
= yield(:webpack_js_chunk)
- begin
= javascript_pack_tag "#{controller_name}-#{action_name}"
- rescue => e
- Bugsnag.notify(e.backtrace)
- if controller_name == "apps"
= javascript_pack_tag "apps/#{@app_details.app_namespace}"
On your individual page haml file add -
- content_for(:webpack_js_chunk) do
= javascript_pack_tag "base-settings-and-react-components"
Example of including the css on page haml file:
- content_for(:webpack_stylesheet_chunk) do
= stylesheet_pack_tag "app-settings-specific"
Including webpack-compiled, non-chunked css on the page
Note: If your component is not used in multiple places, your js and css files will not be chunked. Eg: the react slider component css on users and pricing page.
In this case your manifest.json file will have a css file with name controller-action.css
eg: "users-show.css": "https://localhost:3002/assets/packs/users-show.css"
In this case, you will have to add following in your /users/show.html.haml
- content_for(:webpack_stylesheet_chunk) do
= stylesheet_pack_tag "users-show"
example:
import css
npm install slick-carousel --save
app/javascript/modules/react_components/mini_market_components/mini_market.jsx import "slick-carousel/slick/slick.css"; import "slick-carousel/slick/slick-theme.css";
since it is rendered with user-show.js =>
app/views/users/show.html.haml
- content_for(:webpack_stylesheet_chunk) do
= stylesheet_pack_tag "users-show"
let's also add to /plugins page:
app/views/app_details/index.html.haml
- content_for(:webpack_stylesheet_chunk) do
= stylesheet_pack_tag "app_details-index"
app/views/app_details/show.html.haml
- content_for(:webpack_stylesheet_chunk) do
= stylesheet_pack_tag "app_details-show"
restart server make sure that you have "app_details-index.css": "https://localhost:3002/assets/packs/app_details-index.css", https://localhost:3002/assets/packs/app_details-index.css in public/assets/packs/manifest.json