From 392376871cf7d35dc4efd991a1dc279f20b2b26b Mon Sep 17 00:00:00 2001 From: Gaurav Tiwari Date: Sat, 3 Mar 2018 15:36:23 +0000 Subject: [PATCH] Consitently use NODE_ENV and restructure npm package for clarity (#1304) --- lib/webpacker.rb | 1 + lib/webpacker/dev_server_runner.rb | 2 +- lib/webpacker/env.rb | 39 +++++++++++++ lib/webpacker/instance.rb | 13 +---- package/__tests__/config.js | 8 +-- package/__tests__/dev_server.js | 26 +++++++++ package/__tests__/env.js | 28 ++++++++++ package/__tests__/index.js | 31 ++++++++++ package/config.js | 44 +++++---------- package/config_types/__tests__/config_list.js | 5 -- package/config_types/config_list.js | 9 --- package/dev_server.js | 23 ++++++++ package/env.js | 23 ++++++++ .../__tests__/base.js} | 12 ++-- .../{environment.js => environments/base.js} | 8 +-- package/environments/development.js | 7 ++- package/environments/production.js | 56 ++++++++++--------- package/environments/test.js | 4 +- package/index.js | 16 ++++-- package/rules/babel.js | 14 +++-- package/rules/css.js | 8 +-- package/rules/file.js | 16 +++--- package/rules/module.css.js | 8 +-- package/rules/module.sass.js | 12 ++-- package/rules/sass.js | 12 ++-- package/utils/__tests__/get_style_rule.js | 36 ++++++++++++ .../get_style_rule.js} | 38 +++++++------ package/utils/helpers.js | 20 ++++++- test/env_test.rb | 19 +++++++ test/test_helper.rb | 4 +- 30 files changed, 374 insertions(+), 168 deletions(-) create mode 100644 lib/webpacker/env.rb create mode 100644 package/__tests__/dev_server.js create mode 100644 package/__tests__/env.js create mode 100644 package/__tests__/index.js create mode 100644 package/dev_server.js create mode 100644 package/env.js rename package/{__tests__/environment.js => environments/__tests__/base.js} (89%) rename package/{environment.js => environments/base.js} (94%) create mode 100644 package/utils/__tests__/get_style_rule.js rename package/{rules/style_rule_factory.js => utils/get_style_rule.js} (62%) create mode 100644 test/env_test.rb diff --git a/lib/webpacker.rb b/lib/webpacker.rb index 0b6544ebc..a2bfd47d8 100644 --- a/lib/webpacker.rb +++ b/lib/webpacker.rb @@ -19,6 +19,7 @@ def instance end require "webpacker/instance" +require "webpacker/env" require "webpacker/configuration" require "webpacker/manifest" require "webpacker/compiler" diff --git a/lib/webpacker/dev_server_runner.rb b/lib/webpacker/dev_server_runner.rb index 0648a6b20..8a4b93242 100644 --- a/lib/webpacker/dev_server_runner.rb +++ b/lib/webpacker/dev_server_runner.rb @@ -14,7 +14,7 @@ def run private def load_config @config_file = File.join(@app_path, "config/webpacker.yml") - dev_server = YAML.load_file(@config_file)[ENV["RAILS_ENV"]]["dev_server"] + dev_server = YAML.load_file(@config_file)[ENV["NODE_ENV"]]["dev_server"] @hostname = dev_server["host"] @port = dev_server["port"] diff --git a/lib/webpacker/env.rb b/lib/webpacker/env.rb new file mode 100644 index 000000000..f5b1e5c9e --- /dev/null +++ b/lib/webpacker/env.rb @@ -0,0 +1,39 @@ +class Webpacker::Env + DEFAULT = "production".freeze + + delegate :config_path, :logger, to: :@webpacker + + def self.inquire(webpacker) + new(webpacker).inquire + end + + def initialize(webpacker) + @webpacker = webpacker + end + + def inquire + fallback_env_warning unless current + (current || DEFAULT).inquiry + end + + private + def current + (ENV["NODE_ENV"] || Rails.env).presence_in(available_environments) + end + + def fallback_env_warning + logger.info "NODE_ENV=#{ENV["NODE_ENV"]} and RAILS_ENV=#{Rails.env} environment is not defined in config/webpacker.yml, falling back to #{DEFAULT} environment" + end + + def available_environments + if config_path.exist? + YAML.load(config_path.read).keys + else + [].freeze + end + rescue Psych::SyntaxError => e + raise "YAML syntax error occurred while parsing #{config_path}. " \ + "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ + "Error: #{e.message}" + end +end diff --git a/lib/webpacker/instance.rb b/lib/webpacker/instance.rb index 0775f3b58..1023f9f62 100644 --- a/lib/webpacker/instance.rb +++ b/lib/webpacker/instance.rb @@ -8,9 +8,7 @@ def initialize(root_path: Rails.root, config_path: Rails.root.join("config/webpa end def env - (ENV["NODE_ENV"].presence_in(available_environments) || - Rails.env.presence_in(available_environments) || - "production".freeze).inquiry + @env ||= Webpacker::Env.inquire self end def config @@ -32,13 +30,4 @@ def manifest def commands @commands ||= Webpacker::Commands.new self end - - private - def available_environments - if config_path.exist? - YAML.load(config_path.read).keys - else - [].freeze - end - end end diff --git a/package/__tests__/config.js b/package/__tests__/config.js index e5b6b94cc..acdd99e58 100644 --- a/package/__tests__/config.js +++ b/package/__tests__/config.js @@ -1,12 +1,12 @@ /* global test expect, describe */ -const chdirApp = () => process.chdir('test/test_app') -const chdirCwd = () => process.chdir(process.cwd()) -chdirApp() +const { chdirTestApp, chdirCwd } = require('../utils/helpers') + +chdirTestApp() const config = require('../config') -describe('Webpacker.yml config', () => { +describe('Config', () => { afterAll(chdirCwd) test('should return extensions as listed in app config', () => { diff --git a/package/__tests__/dev_server.js b/package/__tests__/dev_server.js new file mode 100644 index 000000000..6e0b31f4b --- /dev/null +++ b/package/__tests__/dev_server.js @@ -0,0 +1,26 @@ +/* global test expect, describe */ + +const { chdirTestApp, chdirCwd } = require('../utils/helpers') + +chdirTestApp() + +describe('DevServer', () => { + beforeEach(() => jest.resetModules()) + afterAll(chdirCwd) + + test('with NODE_ENV set to development', () => { + process.env.NODE_ENV = 'development' + process.env.WEBPACKER_DEV_SERVER_HOST = '0.0.0.0' + process.env.WEBPACKER_DEV_SERVER_PORT = 5000 + + const devServer = require('../dev_server') + expect(devServer).toBeDefined() + expect(devServer.host).toEqual('0.0.0.0') + expect(devServer.port).toEqual('5000') + }) + + test('with NODE_ENV set to production', () => { + process.env.NODE_ENV = 'production' + expect(require('../dev_server')).toEqual({}) + }) +}) diff --git a/package/__tests__/env.js b/package/__tests__/env.js new file mode 100644 index 000000000..707c9e205 --- /dev/null +++ b/package/__tests__/env.js @@ -0,0 +1,28 @@ +/* global test expect, describe */ + +const { chdirTestApp, chdirCwd } = require('../utils/helpers') + +chdirTestApp() + +describe('Env', () => { + beforeEach(() => jest.resetModules()) + afterAll(chdirCwd) + + test('with NODE_ENV set to development', () => { + process.env.NODE_ENV = 'development' + expect(require('../env')).toEqual('development') + }) + + test('with undefined NODE_ENV and RAILS_ENV set to development', () => { + delete process.env.NODE_ENV + process.env.RAILS_ENV = 'development' + expect(require('../env')).toEqual('development') + }) + + test('with a non-standard environment', () => { + process.env.NODE_ENV = 'foo' + process.env.RAILS_ENV = 'foo' + expect(require('../env')).toEqual('production') + delete process.env.RAILS_ENV + }) +}) diff --git a/package/__tests__/index.js b/package/__tests__/index.js new file mode 100644 index 000000000..9e19e72b9 --- /dev/null +++ b/package/__tests__/index.js @@ -0,0 +1,31 @@ +/* global test expect, describe */ + +const { chdirTestApp, chdirCwd } = require('../utils/helpers') + +chdirTestApp() + +describe('Webpacker', () => { + beforeEach(() => jest.resetModules()) + afterAll(chdirCwd) + + test('with NODE_ENV set to development', () => { + process.env.NODE_ENV = 'development' + const { environment } = require('../index') + expect(environment.toWebpackConfig()).toMatchObject({ + devServer: { + host: 'localhost', + port: 3035 + } + }) + }) + + test('with a non-standard env', () => { + process.env.NODE_ENV = 'staging' + process.env.RAILS_ENV = 'staging' + const { environment } = require('../index') + expect(environment.toWebpackConfig()).toMatchObject({ + devtool: 'nosources-source-map', + stats: 'normal' + }) + }) +}) diff --git a/package/config.js b/package/config.js index 36785e058..24390690c 100644 --- a/package/config.js +++ b/package/config.js @@ -3,41 +3,25 @@ const { safeLoad } = require('js-yaml') const { readFileSync } = require('fs') const deepMerge = require('./utils/deep_merge') const { isArray } = require('./utils/helpers') +const env = require('./env') -const defaultFilePath = require.resolve('../lib/install/config/webpacker.yml') -const filePath = resolve('config', 'webpacker.yml') +const defaultConfigPath = require.resolve('../lib/install/config/webpacker.yml') +const configPath = resolve('config', 'webpacker.yml') -const environment = process.env.NODE_ENV || 'development' -const defaultConfig = safeLoad(readFileSync(defaultFilePath), 'utf8')[environment] -const appConfig = safeLoad(readFileSync(filePath), 'utf8')[environment] +const getConfig = () => { + const defaults = safeLoad(readFileSync(defaultConfigPath), 'utf8')[env] + const app = safeLoad(readFileSync(configPath), 'utf8')[env] -if (isArray(appConfig.extensions) && appConfig.extensions.length) { - delete defaultConfig.extensions -} else { - /* eslint no-console: 0 */ - console.warn('No extensions specified in webpacker.yml, using default extensions\n') -} - -const config = deepMerge(defaultConfig, appConfig) + if (isArray(app.extensions) && app.extensions.length) { + delete defaults.extensions + } -const isBoolean = str => /^true/.test(str) || /^false/.test(str) + const config = deepMerge(defaults, app) -const fetch = key => - (isBoolean(process.env[key]) ? JSON.parse(process.env[key]) : process.env[key]) + config.outputPath = resolve('public', config.public_output_path) + config.publicPath = `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1') -const devServer = (key) => { - const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`) - if (typeof envValue === 'undefined' || envValue === null) return config.dev_server[key] - return envValue + return config } -if (config.dev_server) { - Object.keys(config.dev_server).forEach((key) => { - config.dev_server[key] = devServer(key) - }) -} - -config.outputPath = resolve('public', config.public_output_path) -config.publicPath = `/${config.public_output_path}/`.replace(/([^:]\/)\/+/g, '$1') - -module.exports = config +module.exports = getConfig() diff --git a/package/config_types/__tests__/config_list.js b/package/config_types/__tests__/config_list.js index 26234cd9b..9fb349dd9 100644 --- a/package/config_types/__tests__/config_list.js +++ b/package/config_types/__tests__/config_list.js @@ -8,11 +8,6 @@ test('new', () => { expect(list).toBeInstanceOf(Array) }) -test('set', () => { - const list = new ConfigList() - expect(list.set('key', 'value')).toEqual([{ key: 'key', value: 'value' }]) -}) - test('get', () => { const list = new ConfigList() list.append('key', 'value') diff --git a/package/config_types/config_list.js b/package/config_types/config_list.js index cb9f89c9a..1b8c6d9eb 100644 --- a/package/config_types/config_list.js +++ b/package/config_types/config_list.js @@ -10,15 +10,6 @@ class ConfigList extends Array { return this[index].value } - /** - * @deprecated after the 3.0.2 release and will be removed in the next major release - */ - set(key, value) { - /* eslint no-console: 0 */ - console.warn('set is deprecated! Use append instead') - return this.append(key, value) - } - append(key, value) { return this.add({ key, value }) } diff --git a/package/dev_server.js b/package/dev_server.js new file mode 100644 index 000000000..b00a54c7e --- /dev/null +++ b/package/dev_server.js @@ -0,0 +1,23 @@ +const { isBoolean, isEmpty } = require('./utils/helpers') +const config = require('./config') + +const fetch = (key) => { + const value = process.env[key] + return isBoolean(value) ? JSON.parse(value) : value +} + +const devServer = () => { + const devServerConfig = config.dev_server + + if (devServerConfig) { + Object.keys(devServerConfig).forEach((key) => { + const envValue = fetch(`WEBPACKER_DEV_SERVER_${key.toUpperCase().replace(/_/g, '')}`) + if (isEmpty(envValue)) return devServerConfig[key] + devServerConfig[key] = envValue + }) + } + + return devServerConfig || {} +} + +module.exports = devServer() diff --git a/package/env.js b/package/env.js new file mode 100644 index 000000000..90263b267 --- /dev/null +++ b/package/env.js @@ -0,0 +1,23 @@ +const { resolve } = require('path') +const { safeLoad } = require('js-yaml') +const { readFileSync } = require('fs') + +const configPath = resolve('config', 'webpacker.yml') +const DEFAULT_ENV = 'production' + +const env = () => { + const nodeEnv = process.env.NODE_ENV + const railsEnv = process.env.RAILS_ENV + const config = safeLoad(readFileSync(configPath), 'utf8') + const availableEnvironments = Object.keys(config).join('|') + const regex = new RegExp(availableEnvironments, 'g') + + if (nodeEnv && nodeEnv.match(regex)) return nodeEnv + if (railsEnv && railsEnv.match(regex)) return railsEnv + + /* eslint no-console: 0 */ + console.warn(`NODE_ENV=${nodeEnv} and RAILS_ENV=${railsEnv} environment is not defined in config/webpacker.yml, falling back to ${DEFAULT_ENV}`) + return DEFAULT_ENV +} + +module.exports = env() diff --git a/package/__tests__/environment.js b/package/environments/__tests__/base.js similarity index 89% rename from package/__tests__/environment.js rename to package/environments/__tests__/base.js index f083f70db..d16a6f196 100644 --- a/package/__tests__/environment.js +++ b/package/environments/__tests__/base.js @@ -3,14 +3,14 @@ // environment.js expects to find config/webpacker.yml and resolved modules from // the root of a Rails project -const chdirApp = () => process.chdir('test/test_app') -const chdirCwd = () => process.chdir(process.cwd()) -chdirApp() +const { chdirTestApp, chdirCwd } = require('../../utils/helpers') + +chdirTestApp() const { resolve } = require('path') -const rules = require('../rules') -const { ConfigList } = require('../config_types') -const Environment = require('../environment') +const rules = require('../../rules') +const { ConfigList } = require('../../config_types') +const Environment = require('../base') describe('Environment', () => { afterAll(chdirCwd) diff --git a/package/environment.js b/package/environments/base.js similarity index 94% rename from package/environment.js rename to package/environments/base.js index da42f80be..5b7557b2a 100644 --- a/package/environment.js +++ b/package/environments/base.js @@ -12,9 +12,9 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin') const ManifestPlugin = require('webpack-manifest-plugin') const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') -const { ConfigList, ConfigObject } = require('./config_types') -const rules = require('./rules') -const config = require('./config') +const { ConfigList, ConfigObject } = require('../config_types') +const rules = require('../rules') +const config = require('../config') const getLoaderList = () => { const result = new ConfigList() @@ -85,7 +85,7 @@ const getBaseConfig = () => } }) -module.exports = class Environment { +module.exports = class Base { constructor() { this.loaders = getLoaderList() this.plugins = getPluginList() diff --git a/package/environments/development.js b/package/environments/development.js index 512eed723..1152d86ec 100644 --- a/package/environments/development.js +++ b/package/environments/development.js @@ -1,8 +1,9 @@ const webpack = require('webpack') -const Environment = require('../environment') -const { dev_server: devServer, outputPath: contentBase, publicPath } = require('../config') +const Base = require('./base') +const devServer = require('../dev_server') +const { outputPath: contentBase, publicPath } = require('../config') -module.exports = class extends Environment { +module.exports = class extends Base { constructor() { super() diff --git a/package/environments/production.js b/package/environments/production.js index 4aaf3dbfa..7ec1c63b0 100644 --- a/package/environments/production.js +++ b/package/environments/production.js @@ -1,40 +1,46 @@ const webpack = require('webpack') const CompressionPlugin = require('compression-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') -const Environment = require('../environment') +const Base = require('./base') -module.exports = class extends Environment { +module.exports = class extends Base { constructor() { super() this.plugins.append('ModuleConcatenation', new webpack.optimize.ModuleConcatenationPlugin()) - this.plugins.append('UglifyJs', new UglifyJsPlugin({ - parallel: true, - cache: true, - sourceMap: true, - uglifyOptions: { - ie8: false, - ecma: 8, - warnings: false, - mangle: { - safari10: true - }, - compress: { + this.plugins.append( + 'UglifyJs', + new UglifyJsPlugin({ + parallel: true, + cache: true, + sourceMap: true, + uglifyOptions: { + ie8: false, + ecma: 8, warnings: false, - comparisons: false - }, - output: { - ascii_only: true + mangle: { + safari10: true + }, + compress: { + warnings: false, + comparisons: false + }, + output: { + ascii_only: true + } } - } - })) + }) + ) - this.plugins.append('Compression', new CompressionPlugin({ - asset: '[path].gz[query]', - algorithm: 'gzip', - test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/ - })) + this.plugins.append( + 'Compression', + new CompressionPlugin({ + asset: '[path].gz[query]', + algorithm: 'gzip', + test: /\.(js|css|html|json|ico|svg|eot|otf|ttf)$/ + }) + ) this.config.merge({ devtool: 'nosources-source-map', diff --git a/package/environments/test.js b/package/environments/test.js index 4fe3677a2..cb3d14ba9 100644 --- a/package/environments/test.js +++ b/package/environments/test.js @@ -1,3 +1,3 @@ -const Environment = require('../environment') +const Base = require('./base') -module.exports = class extends Environment {} +module.exports = class extends Base {} diff --git a/package/index.js b/package/index.js index 289853a12..02a74b6bb 100644 --- a/package/index.js +++ b/package/index.js @@ -3,18 +3,22 @@ const { resolve } = require('path') const { existsSync } = require('fs') -const Environment = require('./environment') -const config = require('./config') +const Environment = require('./environments/base') const loaders = require('./rules') +const env = require('./env') +const config = require('./config') +const devServer = require('./dev_server') const createEnvironment = () => { - const path = resolve(__dirname, 'environments', `${process.env.NODE_ENV}.js`) + const path = resolve(__dirname, 'environments', `${env}.js`) const constructor = existsSync(path) ? require(path) : Environment return new constructor() } -const environment = createEnvironment() - module.exports = { - environment, config, loaders, Environment + config, + devServer, + environment: createEnvironment(), + Environment, + loaders } diff --git a/package/rules/babel.js b/package/rules/babel.js index 88c1f32b0..31714ec70 100644 --- a/package/rules/babel.js +++ b/package/rules/babel.js @@ -1,13 +1,15 @@ const { join } = require('path') -const { cache_path } = require('../config') +const { cache_path: cachePath } = require('../config') module.exports = { test: /\.(js|jsx)?(\.erb)?$/, exclude: /node_modules/, - use: [{ - loader: 'babel-loader', - options: { - cacheDirectory: join(cache_path, 'babel-loader') + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: join(cachePath, 'babel-loader') + } } - }] + ] } diff --git a/package/rules/css.js b/package/rules/css.js index 8354040b8..1a0c24ac6 100644 --- a/package/rules/css.js +++ b/package/rules/css.js @@ -1,7 +1,3 @@ -const styleRuleFactory = require('./style_rule_factory') +const getStyleRule = require('../utils/get_style_rule') -module.exports = styleRuleFactory( - /\.(css)$/i, - false, - [] -) +module.exports = getStyleRule(/\.(css)$/i) diff --git a/package/rules/file.js b/package/rules/file.js index 3988e2bec..423836986 100644 --- a/package/rules/file.js +++ b/package/rules/file.js @@ -1,13 +1,15 @@ const { join } = require('path') -const { source_path } = require('../config') +const { source_path: sourcePath } = require('../config') module.exports = { test: /\.(jpg|jpeg|png|gif|tiff|ico|svg|eot|otf|ttf|woff|woff2)$/i, - use: [{ - loader: 'file-loader', - options: { - name: '[path][name]-[hash].[ext]', - context: join(source_path) + use: [ + { + loader: 'file-loader', + options: { + name: '[path][name]-[hash].[ext]', + context: join(sourcePath) + } } - }] + ] } diff --git a/package/rules/module.css.js b/package/rules/module.css.js index 6671d8548..6c70ec884 100644 --- a/package/rules/module.css.js +++ b/package/rules/module.css.js @@ -1,7 +1,3 @@ -const styleRuleFactory = require('./style_rule_factory') +const getStyleRule = require('../utils/get_style_rule') -module.exports = styleRuleFactory( - /\.(css)$/i, - true, - [] -) +module.exports = getStyleRule(/\.(css)$/i, true) diff --git a/package/rules/module.sass.js b/package/rules/module.sass.js index 9a8f01a4f..6681d2d46 100644 --- a/package/rules/module.sass.js +++ b/package/rules/module.sass.js @@ -1,10 +1,8 @@ -const styleRuleFactory = require('./style_rule_factory') +const getStyleRule = require('../utils/get_style_rule') -module.exports = styleRuleFactory( - /\.(scss|sass)$/i, - true, - [{ +module.exports = getStyleRule(/\.(scss|sass)$/i, true, [ + { loader: 'sass-loader', options: { sourceMap: true } - }] -) + } +]) diff --git a/package/rules/sass.js b/package/rules/sass.js index 41cec0899..568733799 100644 --- a/package/rules/sass.js +++ b/package/rules/sass.js @@ -1,10 +1,8 @@ -const styleRuleFactory = require('./style_rule_factory') +const getStyleRule = require('../utils/get_style_rule') -module.exports = styleRuleFactory( - /\.(scss|sass)$/i, - false, - [{ +module.exports = getStyleRule(/\.(scss|sass)$/i, false, [ + { loader: 'sass-loader', options: { sourceMap: true } - }] -) + } +]) diff --git a/package/utils/__tests__/get_style_rule.js b/package/utils/__tests__/get_style_rule.js new file mode 100644 index 000000000..a548d16f9 --- /dev/null +++ b/package/utils/__tests__/get_style_rule.js @@ -0,0 +1,36 @@ +const { chdirTestApp, chdirCwd } = require('../helpers') + +chdirTestApp() + +const getStyleRule = require('../get_style_rule') + +describe('getStyleRule', () => { + afterAll(chdirCwd) + + test('excludes modules by default', () => { + const cssRule = getStyleRule(/\.(css)$/i) + const expectation = { + test: /\.(css)$/i, + exclude: /\.module\.[a-z]+$/ + } + + expect(cssRule).toMatchObject(expectation) + }) + + test('includes modules if set to true', () => { + const cssRule = getStyleRule(/\.(scss)$/i, true) + const expectation = { + test: /\.(scss)$/i, + include: /\.module\.[a-z]+$/ + } + + expect(cssRule).toMatchObject(expectation) + }) + + test('adds extra preprocessors if supplied', () => { + const expectation = [{ foo: 'bar' }] + const cssRule = getStyleRule(/\.(css)$/i, true, expectation) + + expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation)) + }) +}) diff --git a/package/rules/style_rule_factory.js b/package/utils/get_style_rule.js similarity index 62% rename from package/rules/style_rule_factory.js rename to package/utils/get_style_rule.js index a6d9bf6a5..d5a0e266b 100644 --- a/package/rules/style_rule_factory.js +++ b/package/utils/get_style_rule.js @@ -1,60 +1,62 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin') const path = require('path') -const { dev_server: devServer } = require('../config') +const devServer = require('../dev_server') const postcssConfigPath = path.resolve(process.cwd(), '.postcssrc.yml') const isProduction = process.env.NODE_ENV === 'production' const inDevServer = process.argv.find(v => v.includes('webpack-dev-server')) const isHMR = inDevServer && (devServer && devServer.hmr) -const extractCSS = !(isHMR) || isProduction - -const styleRuleFactory = (test, modules, preprocessors) => { - const styleLoader = { - loader: 'style-loader', - options: { - hmr: isHMR, - sourceMap: true - } +const extractCSS = !isHMR || isProduction + +const styleLoader = { + loader: 'style-loader', + options: { + hmr: isHMR, + sourceMap: true } +} +const getStyleRule = (test, modules = false, preprocessors = []) => { const extractOptions = { fallback: styleLoader, use: [ { loader: 'css-loader', options: { - minimize: isProduction, sourceMap: true, importLoaders: 2, modules + minimize: isProduction, + sourceMap: true, + importLoaders: 2, + modules } }, { loader: 'postcss-loader', options: { - sourceMap: true, config: { path: postcssConfigPath } + sourceMap: true, + config: { path: postcssConfigPath } } }, ...preprocessors ] } - const modulesCondition = modules - ? { include: /\.module\.[a-z]+$/ } - : { exclude: /\.module\.[a-z]+$/ } + const options = modules ? { include: /\.module\.[a-z]+$/ } : { exclude: /\.module\.[a-z]+$/ } // For production extract styles to a separate bundle const extractCSSLoader = Object.assign( {}, { test, use: ExtractTextPlugin.extract(extractOptions) }, - modulesCondition + options ) // For hot-reloading use regular loaders const inlineCSSLoader = Object.assign( {}, { test, use: [styleLoader].concat(extractOptions.use) }, - modulesCondition + options ) return extractCSS ? extractCSSLoader : inlineCSSLoader } -module.exports = styleRuleFactory +module.exports = getStyleRule diff --git a/package/utils/helpers.js b/package/utils/helpers.js index e3a11cc6c..ef910aeaf 100644 --- a/package/utils/helpers.js +++ b/package/utils/helpers.js @@ -1,10 +1,11 @@ -const isObject = value => ( +const isObject = value => typeof value === 'object' && value !== null && (value.length === undefined || value.length === null) -) -const isEmpty = value => (value === null || value === undefined) +const isBoolean = str => /^true/.test(str) || /^false/.test(str) + +const isEmpty = value => value === null || value === undefined const isString = key => key && typeof key === 'string' @@ -21,8 +22,21 @@ const canMerge = value => isObject(value) || isArray(value) const prettyPrint = obj => JSON.stringify(obj, null, 2) +const chdirTestApp = () => { + try { + return process.chdir('test/test_app') + } catch (e) { + return null + } +} + +const chdirCwd = () => process.chdir(process.cwd()) + module.exports = { + chdirTestApp, + chdirCwd, isObject, + isBoolean, isArray, isEqual, isEmpty, diff --git a/test/env_test.rb b/test/env_test.rb new file mode 100644 index 000000000..1fc743011 --- /dev/null +++ b/test/env_test.rb @@ -0,0 +1,19 @@ +require "test_helper" + +class EnvTest < Webpacker::Test + def test_current + reloaded_config + assert_equal Webpacker.env, "production" + end + + def test_custom + with_node_env("default") do + reloaded_config + assert_equal Webpacker.env, "default" + end + end + + def test_default + assert_equal Webpacker::Env::DEFAULT, "production" + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index c7f8f972f..54b7d30eb 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,7 +6,7 @@ require_relative "test_app/config/environment" -ENV["NODE_ENV"] ||= "production" +ENV["NODE_ENV"] = "production" Webpacker.instance = Webpacker::Instance.new \ root_path: Pathname.new(File.expand_path("test_app", __dir__)), @@ -15,7 +15,9 @@ class Webpacker::Test < Minitest::Test private def reloaded_config + Webpacker.instance.instance_variable_set(:@env, nil) Webpacker.instance.instance_variable_set(:@config, nil) + Webpacker.env Webpacker.config end