From 11bbe2cafab723efb159833fe831ccfb1e5499ec Mon Sep 17 00:00:00 2001 From: Artem Sapegin Date: Mon, 11 Dec 2017 10:22:04 +0100 Subject: [PATCH] Fix: Use webpack.DefinePlugin as recommended by webpack docs Fixes #726 --- .../make-webpack-config.spec.js.snap | 217 ++++++++++++++++++ scripts/__tests__/make-webpack-config.spec.js | 93 ++++++++ scripts/make-webpack-config.js | 6 +- 3 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 scripts/__tests__/__snapshots__/make-webpack-config.spec.js.snap create mode 100644 scripts/__tests__/make-webpack-config.spec.js diff --git a/scripts/__tests__/__snapshots__/make-webpack-config.spec.js.snap b/scripts/__tests__/__snapshots__/make-webpack-config.spec.js.snap new file mode 100644 index 000000000..3e6302836 --- /dev/null +++ b/scripts/__tests__/__snapshots__/make-webpack-config.spec.js.snap @@ -0,0 +1,217 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should enable verbose mode in CleanWebpackPlugin 1`] = ` +Array [ + CleanWebpackPlugin { + "options": Object { + "allowExternal": false, + "dry": false, + "root": "~/scripts/__tests__", + "verbose": true, + }, + "paths": Array [ + "build", + ], + }, +] +`; + +exports[`should merge user webpack config 1`] = ` +Object { + "foo": "bar", + "rsg-codemirror-theme.css": "codemirror/theme/hl-theme.css", + "rsg-components": "~/lib/rsg-components", +} +`; + +exports[`should not owerwrite user DefinePlugin 1`] = ` +Array [ + DefinePlugin { + "definitions": Object { + "process.env.NODE_ENV": "\\"test\\"", + "process.env.STYLEGUIDIST_ENV": "\\"development\\"", + }, + }, + DefinePlugin { + "definitions": Object { + "process.env.PIZZA": "\\"salami\\"", + }, + }, +] +`; + +exports[`should prepend requires as webpack entries 1`] = ` +Array [ + "a/b.js", + "c/d.css", + "~/lib/index", + "~/node_modules/react-dev-utils/webpackHotDevClient.js", +] +`; + +exports[`should return a development config 1`] = ` +Object { + "entry": Array [ + "~/lib/index", + "~/node_modules/react-dev-utils/webpackHotDevClient.js", + ], + "output": Object { + "chunkFilename": "build/[name].js", + "filename": "build/[name].bundle.js", + "path": "~/scripts/__tests__", + }, + "performance": Object { + "hints": false, + }, + "plugins": Array [ + StyleguidistOptionsPlugin { + "options": Object { + "highlightTheme": "hl-theme", + "require": Array [], + "styleguideDir": "~/scripts/__tests__", + "template": "template.html", + "title": "Style Guide", + }, + }, + HtmlWebpackPlugin { + "options": Object { + "cache": true, + "chunks": "all", + "compile": true, + "excludeChunks": Array [], + "favicon": false, + "filename": "index.html", + "hash": false, + "inject": true, + "minify": false, + "showErrors": true, + "template": "!!~/node_modules/html-webpack-plugin/lib/loader.js!template.html", + "title": "Style Guide", + "xhtml": false, + }, + }, + DefinePlugin { + "definitions": Object { + "process.env.NODE_ENV": "\\"test\\"", + "process.env.STYLEGUIDIST_ENV": "\\"development\\"", + }, + }, + HotModuleReplacementPlugin { + "fullBuildTimeout": 200, + "multiStep": undefined, + "options": Object {}, + "requestTimeout": 10000, + }, + ], + "resolve": Object { + "alias": Object { + "rsg-codemirror-theme.css": "codemirror/theme/hl-theme.css", + "rsg-components": "~/lib/rsg-components", + }, + "extensions": Array [ + ".js", + ".jsx", + ".json", + ], + }, +} +`; + +exports[`should return a production config 1`] = ` +Object { + "entry": Array [ + "~/lib/index", + ], + "output": Object { + "chunkFilename": "build/[name].[chunkhash:8].js", + "filename": "build/bundle.[chunkhash:8].js", + "path": "~/scripts/__tests__", + }, + "performance": Object { + "hints": false, + }, + "plugins": Array [ + StyleguidistOptionsPlugin { + "options": Object { + "highlightTheme": "hl-theme", + "require": Array [], + "styleguideDir": "~/scripts/__tests__", + "template": "template.html", + "title": "Style Guide", + }, + }, + HtmlWebpackPlugin { + "options": Object { + "cache": true, + "chunks": "all", + "compile": true, + "excludeChunks": Array [], + "favicon": false, + "filename": "index.html", + "hash": false, + "inject": true, + "minify": false, + "showErrors": true, + "template": "!!~/node_modules/html-webpack-plugin/lib/loader.js!template.html", + "title": "Style Guide", + "xhtml": false, + }, + }, + DefinePlugin { + "definitions": Object { + "process.env.NODE_ENV": "\\"test\\"", + "process.env.STYLEGUIDIST_ENV": "\\"production\\"", + }, + }, + UglifyJsPlugin { + "options": Object { + "cache": true, + "extractComments": false, + "parallel": true, + "sourceMap": false, + "test": /\\\\\\.js\\$/i, + "uglifyOptions": Object { + "compress": Object { + "keep_fnames": true, + "warnings": false, + }, + "ecma": 5, + "ie8": false, + "mangle": Object { + "keep_fnames": true, + }, + "output": Object { + "comments": /\\^\\\\\\*\\*!\\|@preserve\\|@license\\|@cc_on/, + }, + }, + "warningsFilter": [Function], + }, + }, + CleanWebpackPlugin { + "options": Object { + "allowExternal": false, + "dry": false, + "root": "~/scripts/__tests__", + "verbose": false, + }, + "paths": Array [ + "build", + ], + }, + Object { + "apply": [Function], + }, + ], + "resolve": Object { + "alias": Object { + "rsg-codemirror-theme.css": "codemirror/theme/hl-theme.css", + "rsg-components": "~/lib/rsg-components", + }, + "extensions": Array [ + ".js", + ".jsx", + ".json", + ], + }, +} +`; diff --git a/scripts/__tests__/make-webpack-config.spec.js b/scripts/__tests__/make-webpack-config.spec.js new file mode 100644 index 000000000..d9605f8f5 --- /dev/null +++ b/scripts/__tests__/make-webpack-config.spec.js @@ -0,0 +1,93 @@ +import webpack from 'webpack'; +import makeWebpackConfig from '../make-webpack-config'; + +const styleguideConfig = { + styleguideDir: __dirname, + require: [], + highlightTheme: 'hl-theme', + title: 'Style Guide', + template: 'template.html', +}; + +const process$env$nodeEnv = process.env.NODE_ENV; + +afterEach(() => { + process.env.NODE_ENV = process$env$nodeEnv; +}); + +it('should return a development config', () => { + const result = makeWebpackConfig(styleguideConfig, 'development'); + expect(result).toMatchSnapshot(); +}); + +it('should return a production config', () => { + const result = makeWebpackConfig(styleguideConfig, 'production'); + expect(result).toMatchSnapshot(); +}); + +it('should prepend requires as webpack entries', () => { + const result = makeWebpackConfig( + { ...styleguideConfig, require: ['a/b.js', 'c/d.css'] }, + 'development' + ); + expect(result.entry).toMatchSnapshot(); +}); + +it('should enable verbose mode in CleanWebpackPlugin', () => { + const result = makeWebpackConfig({ ...styleguideConfig, verbose: true }, 'production'); + expect(result.plugins.filter(x => x.constructor.name === 'CleanWebpackPlugin')).toMatchSnapshot(); +}); + +it('should merge user webpack config', () => { + const result = makeWebpackConfig( + { ...styleguideConfig, webpackConfig: { resolve: { alias: { foo: 'bar' } } } }, + 'development' + ); + expect(result.resolve.alias).toMatchSnapshot(); +}); + +it('should not owerwrite user DefinePlugin', () => { + const result = makeWebpackConfig( + { + ...styleguideConfig, + webpackConfig: { + plugins: [ + new webpack.DefinePlugin({ + 'process.env.PIZZA': JSON.stringify('salami'), + }), + ], + }, + }, + 'development' + ); + + // Doesn’t really test that values won’t be overwritten, just that DefinePlugin is applied twice + // To write a real test we’d have to run webpack + expect(result.plugins.filter(x => x.constructor.name === 'DefinePlugin')).toMatchSnapshot(); +}); + +it('should update webpack config', () => { + const extensions = ['.web.js', '.js']; + const result = makeWebpackConfig( + { + ...styleguideConfig, + dangerouslyUpdateWebpackConfig: c => { + c.resolve.extensions = extensions; + return c; + }, + }, + 'development' + ); + expect(result.resolve.extensions).toEqual(extensions); +}); + +it('should update NODE_ENV', () => { + process.env.NODE_ENV = ''; + makeWebpackConfig(styleguideConfig, 'production'); + expect(process.env.NODE_ENV).toBe('production'); +}); + +it('should not overwrite NODE_ENV', () => { + makeWebpackConfig(styleguideConfig, 'production'); + expect(process.env.NODE_ENV).toBe(process$env$nodeEnv); +}); diff --git a/scripts/make-webpack-config.js b/scripts/make-webpack-config.js index 432d4e9a7..a5b54a2d3 100644 --- a/scripts/make-webpack-config.js +++ b/scripts/make-webpack-config.js @@ -42,10 +42,8 @@ module.exports = function(config, env) { inject: true, }), new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify(process.env.NODE_ENV), - STYLEGUIDIST_ENV: JSON.stringify(env), - }, + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), + 'process.env.STYLEGUIDIST_ENV': JSON.stringify(env), }), ], performance: {