From 41d79c96187154b5485289e8c3c42428dd819bfc Mon Sep 17 00:00:00 2001 From: Taiju Muto Date: Sat, 15 Dec 2018 05:47:07 +0900 Subject: [PATCH] Separate css extraction from build environment (#1625) --- docs/css.md | 1 + lib/install/config/webpacker.yml | 3 +++ lib/webpacker/configuration.rb | 4 ++++ lib/webpacker/helper.rb | 18 +++++++++--------- package/utils/__tests__/get_style_rule.js | 20 ++++++++++++++++++++ package/utils/get_style_rule.js | 5 ++--- test/helper_test.rb | 13 ++++++++----- test/test_app/config/webpacker.yml | 6 ++++++ 8 files changed, 53 insertions(+), 17 deletions(-) diff --git a/docs/css.md b/docs/css.md index e4964e0c7..127901f03 100644 --- a/docs/css.md +++ b/docs/css.md @@ -72,6 +72,7 @@ a separate `[pack_name].css` bundle so that in your view you can use the <%= stylesheet_pack_tag 'hello_react' %> ``` +Webpacker emits css files only if `extract_css` is set to true in webpacker.yml otherwise `stylesheet_pack_tag` returns nil. ## Add bootstrap diff --git a/lib/install/config/webpacker.yml b/lib/install/config/webpacker.yml index b0ff7b496..2bc3a4cb4 100644 --- a/lib/install/config/webpacker.yml +++ b/lib/install/config/webpacker.yml @@ -84,5 +84,8 @@ production: # Production depends on precompilation of packs prior to booting for performance. compile: false + # Emit css as a file + extract_css: true + # Cache manifest.json for performance cache_manifest: true diff --git a/lib/webpacker/configuration.rb b/lib/webpacker/configuration.rb index 5153ea465..3ebc0e086 100644 --- a/lib/webpacker/configuration.rb +++ b/lib/webpacker/configuration.rb @@ -71,6 +71,10 @@ def webpack_compile_output? fetch(:webpack_compile_output) end + def extract_css? + fetch(:extract_css) + end + private def fetch(key) data.fetch(key, defaults[key]) diff --git a/lib/webpacker/helper.rb b/lib/webpacker/helper.rb index 5142343c4..53ddf9a3d 100644 --- a/lib/webpacker/helper.rb +++ b/lib/webpacker/helper.rb @@ -5,13 +5,13 @@ module Webpacker::Helper # # Example: # - # # In development mode with hot module replacement: + # # When extract_css is false in webpacker.yml and the file is a css: # <%= asset_pack_path 'calendar.css' %> # => nil # - # # In production mode: + # # When extract_css is true in webpacker.yml or the file is not a css: # <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css" def asset_pack_path(name, **options) - unless stylesheet?(name) && Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing? + if Webpacker.config.extract_css? || !stylesheet?(name) asset_path(Webpacker.manifest.lookup!(name), **options) end end @@ -22,13 +22,13 @@ def asset_pack_path(name, **options) # # Example: # - # # In development mode with hot module replacement: + # # When extract_css is false in webpacker.yml and the file is a css: # <%= asset_pack_url 'calendar.css' %> # => nil # - # # In production mode: + # # When extract_css is true in webpacker.yml or the file is not a css: # <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css" def asset_pack_url(name, **options) - unless Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing? + if Webpacker.config.extract_css? || !stylesheet?(name) asset_url(Webpacker.manifest.lookup!(name), **options) end end @@ -64,15 +64,15 @@ def javascript_pack_tag(*names, **options) # # Examples: # - # # In development mode with hot module replacement: + # # When extract_css is false in webpacker.yml: # <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # => # nil # - # # In production mode: + # # When extract_css is true in webpacker.yml: # <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # => # def stylesheet_pack_tag(*names, **options) - unless Webpacker.dev_server.running? && Webpacker.dev_server.hot_module_replacing? + if Webpacker.config.extract_css? stylesheet_link_tag(*sources_from_pack_manifest(names, type: :stylesheet), **options) end end diff --git a/package/utils/__tests__/get_style_rule.js b/package/utils/__tests__/get_style_rule.js index a548d16f9..5fcbbbf2e 100644 --- a/package/utils/__tests__/get_style_rule.js +++ b/package/utils/__tests__/get_style_rule.js @@ -33,4 +33,24 @@ describe('getStyleRule', () => { expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation)) }) + + test('adds mini-css-extract-plugin when extract_css is true', () => { + const MiniCssExtractPlugin = require('mini-css-extract-plugin') + const expectation = [MiniCssExtractPlugin.loader] + + require('../../config').extract_css = true + const cssRule = getStyleRule(/\.(css)$/i) + + expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation)) + }) + + test(`doesn't add mini-css-extract-plugin when extract_css is false`, () => { + const MiniCssExtractPlugin = require('mini-css-extract-plugin') + const expectation = [MiniCssExtractPlugin.loader] + + require('../../config').extract_css = false + const cssRule = getStyleRule(/\.(css)$/i) + + expect(cssRule.use).toMatchObject(expect.not.arrayContaining(expectation)) + }) }) diff --git a/package/utils/get_style_rule.js b/package/utils/get_style_rule.js index 218c4c02a..d1921183f 100644 --- a/package/utils/get_style_rule.js +++ b/package/utils/get_style_rule.js @@ -1,11 +1,10 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin') const { resolve } = require('path') const devServer = require('../dev_server') -const { nodeEnv } = require('../env') +const config = require('../config') const inDevServer = process.argv.find(v => v.includes('webpack-dev-server')) const isHMR = inDevServer && (devServer && devServer.hmr) -const extractCSS = !isHMR || nodeEnv === 'production' const styleLoader = { loader: 'style-loader', @@ -38,7 +37,7 @@ const getStyleRule = (test, modules = false, preprocessors = []) => { const options = modules ? { include: /\.module\.[a-z]+$/ } : { exclude: /\.module\.[a-z]+$/ } - if (extractCSS) { + if (config.extract_css) { use.unshift(MiniCssExtractPlugin.loader) } else { use.unshift(styleLoader) diff --git a/test/helper_test.rb b/test/helper_test.rb index b097dd13d..aeef8fb98 100644 --- a/test/helper_test.rb +++ b/test/helper_test.rb @@ -18,17 +18,20 @@ def test_asset_pack_path assert_equal "/packs/bootstrap-300631c4f0e0f9c865bc.js", asset_pack_path("bootstrap.js") assert_equal "/packs/bootstrap-c38deda30895059837cf.css", asset_pack_path("bootstrap.css") - Webpacker.dev_server.stub :running?, true do - Webpacker.dev_server.stub :hot_module_replacing?, true do - assert_nil asset_pack_path("bootstrap.css") - assert_equal "/packs/application-k344a6d59eef8632c9d1.png", asset_pack_path("application.png") - end + Webpacker.config.stub :extract_css?, false do + assert_nil asset_pack_path("bootstrap.css") + assert_equal "/packs/application-k344a6d59eef8632c9d1.png", asset_pack_path("application.png") end end def test_asset_pack_url assert_equal "https://example.com/packs/bootstrap-300631c4f0e0f9c865bc.js", asset_pack_url("bootstrap.js") assert_equal "https://example.com/packs/bootstrap-c38deda30895059837cf.css", asset_pack_url("bootstrap.css") + + Webpacker.config.stub :extract_css?, false do + assert_nil asset_pack_path("bootstrap.css") + assert_equal "https://example.com/packs/application-k344a6d59eef8632c9d1.png", asset_pack_url("application.png") + end end def test_image_pack_tag diff --git a/test/test_app/config/webpacker.yml b/test/test_app/config/webpacker.yml index 79d7b921f..6207e3a87 100644 --- a/test/test_app/config/webpacker.yml +++ b/test/test_app/config/webpacker.yml @@ -75,6 +75,9 @@ production: # Production depends on precompilation of packs prior to booting for performance. compile: false + # Emit css as a file + extract_css: true + # Cache manifest.json for performance cache_manifest: true @@ -84,6 +87,9 @@ staging: # Production depends on precompilation of packs prior to booting for performance. compile: false + # Emit css as a file + extract_css: true + # Cache manifest.json for performance cache_manifest: true