From b653641e7993eb28fad70c1733dc45feafea93c5 Mon Sep 17 00:00:00 2001 From: SergeyPanchenkoWeWork <45940051+SergeyPanchenkoWeWork@users.noreply.github.com> Date: Tue, 5 Feb 2019 18:49:07 +0200 Subject: [PATCH 01/30] feat: added error code to chunk load Error (#347) --- src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.js b/src/index.js index 3e2a9001..c905bb82 100644 --- a/src/index.js +++ b/src/index.js @@ -359,6 +359,7 @@ class MiniCssExtractPlugin { Template.indent([ 'var request = event && event.target && event.target.src || fullhref;', 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");', + 'err.code = "CSS_CHUNK_LOAD_FAILED";', 'err.request = request;', 'delete installedCssChunks[chunkId]', 'linkTag.parentNode.removeChild(linkTag)', From 272910c616b31f825979a0675c79cab29d8f9a4e Mon Sep 17 00:00:00 2001 From: Even Stensberg Date: Mon, 25 Mar 2019 11:16:03 +0100 Subject: [PATCH 02/30] docs: uglify -> terser (#350) --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 072cb1ff..beb5620a 100644 --- a/README.md +++ b/README.md @@ -121,17 +121,13 @@ While webpack 5 is likely to come with a CSS minimizer built-in, with webpack 4 **webpack.config.js** ```js -const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); +const TerserJSPlugin = require("terser-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); module.exports = { optimization: { minimizer: [ - new UglifyJsPlugin({ - cache: true, - parallel: true, - sourceMap: true // set to true if you want JS source maps - }), + new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({}) ] }, From 7b1425a2e4578cd9017a124f010ee3bf80fe7789 Mon Sep 17 00:00:00 2001 From: Karl von Randow Date: Tue, 9 Apr 2019 04:09:40 +1200 Subject: [PATCH 03/30] feat: publicPath can be a function (#373) --- README.md | 46 +++++++++++++++++++ src/loader.js | 12 ++++- src/options.json | 19 ++++++++ test/TestCases.test.js | 37 ++++++++++----- .../expected/nested/again/style.css | 2 + .../expected/nested/style.css | 2 + .../nested/again/style.css | 1 + .../publicpath-function/nested/style.css | 1 + test/cases/publicpath-function/react.svg | 1 + .../publicpath-function/webpack.config.js | 41 +++++++++++++++++ .../expected/main.css | 2 + test/cases/publicpath-trailing-slash/index.js | 1 + .../cases/publicpath-trailing-slash/react.svg | 1 + .../cases/publicpath-trailing-slash/style.css | 1 + .../webpack.config.js | 34 ++++++++++++++ 15 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 src/options.json create mode 100644 test/cases/publicpath-function/expected/nested/again/style.css create mode 100644 test/cases/publicpath-function/expected/nested/style.css create mode 100644 test/cases/publicpath-function/nested/again/style.css create mode 100644 test/cases/publicpath-function/nested/style.css create mode 100644 test/cases/publicpath-function/react.svg create mode 100644 test/cases/publicpath-function/webpack.config.js create mode 100644 test/cases/publicpath-trailing-slash/expected/main.css create mode 100644 test/cases/publicpath-trailing-slash/index.js create mode 100644 test/cases/publicpath-trailing-slash/react.svg create mode 100644 test/cases/publicpath-trailing-slash/style.css create mode 100644 test/cases/publicpath-trailing-slash/webpack.config.js diff --git a/README.md b/README.md index beb5620a..72c21d77 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,13 @@ npm install --save-dev mini-css-extract-plugin ### Configuration +#### `publicPath` + +Type: `String|Function` +Default: the `publicPath` in `webpackOptions.output` + +Specifies a custom public path for the target file(s). + #### Minimal example **webpack.config.js** @@ -74,6 +81,45 @@ module.exports = { } ``` +#### `publicPath` function example + +**webpack.config.js** + +```js +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +module.exports = { + plugins: [ + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: "[name].css", + chunkFilename: "[id].css" + }) + ], + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: MiniCssExtractPlugin.loader, + options: { + publicPath: (resourcePath, context) => { + // publicPath is the relative path of the resource to the context + // e.g. for ./css/admin/main.css the publicPath will be ../../ + // while for ./css/main.css the publicPath will be ../ + return path.relative(path.dirname(resourcePath), context) + '/' + }, + } + }, + "css-loader" + ] + } + ] + } +} +``` + #### Advanced configuration example This plugin should be used only on `production` builds without `style-loader` in the loaders chain, especially if you want to have HMR in `development`. diff --git a/src/loader.js b/src/loader.js index 9801d590..5eafa7ab 100644 --- a/src/loader.js +++ b/src/loader.js @@ -6,6 +6,9 @@ import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin'; import LibraryTemplatePlugin from 'webpack/lib/LibraryTemplatePlugin'; import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin'; import LimitChunkCountPlugin from 'webpack/lib/optimize/LimitChunkCountPlugin'; +import validateOptions from 'schema-utils'; + +import schema from './options.json'; const MODULE_TYPE = 'css/mini-extract'; const pluginName = 'mini-css-extract-plugin'; @@ -29,12 +32,19 @@ const findModuleById = (modules, id) => { export function pitch(request) { const query = loaderUtils.getOptions(this) || {}; + + validateOptions(schema, query, 'Mini CSS Extract Plugin Loader'); + const loaders = this.loaders.slice(this.loaderIndex + 1); this.addDependency(this.resourcePath); const childFilename = '*'; // eslint-disable-line no-path-concat const publicPath = typeof query.publicPath === 'string' - ? query.publicPath + ? query.publicPath.endsWith('/') + ? query.publicPath + : `${query.publicPath}/` + : typeof query.publicPath === 'function' + ? query.publicPath(this.resourcePath, this.rootContext) : this._compilation.outputOptions.publicPath; const outputOptions = { filename: childFilename, diff --git a/src/options.json b/src/options.json new file mode 100644 index 00000000..1c6eef18 --- /dev/null +++ b/src/options.json @@ -0,0 +1,19 @@ +{ + "additionalProperties": true, + "properties": { + "publicPath": { + "anyOf": [ + { + "type": "string" + }, + { + "instanceof": "Function" + } + ] + } + }, + "errorMessages": { + "publicPath": "should be {String} or {Function} (https://github.com/webpack-contrib/mini-css-extract-plugin#publicpath)" + }, + "type": "object" + } diff --git a/test/TestCases.test.js b/test/TestCases.test.js index ee4cd52c..10a49bf0 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -59,18 +59,33 @@ describe('TestCases', () => { ); return; } - const expectedDirectory = path.resolve(directoryForCase, 'expected'); - for (const file of fs.readdirSync(expectedDirectory)) { - const content = fs.readFileSync( - path.resolve(expectedDirectory, file), - 'utf-8' - ); - const actualContent = fs.readFileSync( - path.resolve(outputDirectoryForCase, file), - 'utf-8' - ); - expect(actualContent).toEqual(content); + + function compareDirectory(actual, expected) { + for (const file of fs.readdirSync(expected, { + withFileTypes: true, + })) { + if (file.isFile()) { + const content = fs.readFileSync( + path.resolve(expected, file.name), + 'utf-8' + ); + const actualContent = fs.readFileSync( + path.resolve(actual, file.name), + 'utf-8' + ); + expect(actualContent).toEqual(content); + } else if (file.isDirectory()) { + compareDirectory( + path.resolve(actual, file.name), + path.resolve(expected, file.name) + ); + } + } } + + const expectedDirectory = path.resolve(directoryForCase, 'expected'); + compareDirectory(outputDirectoryForCase, expectedDirectory); + done(); }); }, 10000); diff --git a/test/cases/publicpath-function/expected/nested/again/style.css b/test/cases/publicpath-function/expected/nested/again/style.css new file mode 100644 index 00000000..7fbc7c53 --- /dev/null +++ b/test/cases/publicpath-function/expected/nested/again/style.css @@ -0,0 +1,2 @@ +body { background: green; background-image: url(../../cd0bb358c45b584743d8ce4991777c42.svg); } + diff --git a/test/cases/publicpath-function/expected/nested/style.css b/test/cases/publicpath-function/expected/nested/style.css new file mode 100644 index 00000000..aff4e2be --- /dev/null +++ b/test/cases/publicpath-function/expected/nested/style.css @@ -0,0 +1,2 @@ +body { background: red; background-image: url(../cd0bb358c45b584743d8ce4991777c42.svg); } + diff --git a/test/cases/publicpath-function/nested/again/style.css b/test/cases/publicpath-function/nested/again/style.css new file mode 100644 index 00000000..c21a33c8 --- /dev/null +++ b/test/cases/publicpath-function/nested/again/style.css @@ -0,0 +1 @@ +body { background: green; background-image: url(../../react.svg); } diff --git a/test/cases/publicpath-function/nested/style.css b/test/cases/publicpath-function/nested/style.css new file mode 100644 index 00000000..c6261084 --- /dev/null +++ b/test/cases/publicpath-function/nested/style.css @@ -0,0 +1 @@ +body { background: red; background-image: url(../react.svg); } diff --git a/test/cases/publicpath-function/react.svg b/test/cases/publicpath-function/react.svg new file mode 100644 index 00000000..5b3b22a4 --- /dev/null +++ b/test/cases/publicpath-function/react.svg @@ -0,0 +1 @@ +logo-on-dark-bg \ No newline at end of file diff --git a/test/cases/publicpath-function/webpack.config.js b/test/cases/publicpath-function/webpack.config.js new file mode 100644 index 00000000..e7154f5e --- /dev/null +++ b/test/cases/publicpath-function/webpack.config.js @@ -0,0 +1,41 @@ +const Self = require('../../../'); +const path = require('path') + +module.exports = { + entry: { + // Specific CSS entry point, with output to a nested folder + 'nested/style': './nested/style.css', + // Note that relative nesting of output is the same as that of the input + 'nested/again/style': './nested/again/style.css', + }, + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + options: { + // Compute publicPath relative to the CSS output + publicPath: (resourcePath, context) => path.relative(path.dirname(resourcePath), context) + '/', + } + }, + 'css-loader', + ], + }, { + test: /\.(svg|png)$/, + use: [{ + loader: 'file-loader', + options: { + filename: '[name].[ext]' + } + }] + } + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +}; diff --git a/test/cases/publicpath-trailing-slash/expected/main.css b/test/cases/publicpath-trailing-slash/expected/main.css new file mode 100644 index 00000000..6073c14a --- /dev/null +++ b/test/cases/publicpath-trailing-slash/expected/main.css @@ -0,0 +1,2 @@ +body { background: red; background-image: url(/static/img/cd0bb358c45b584743d8ce4991777c42.svg); } + diff --git a/test/cases/publicpath-trailing-slash/index.js b/test/cases/publicpath-trailing-slash/index.js new file mode 100644 index 00000000..aa3357bf --- /dev/null +++ b/test/cases/publicpath-trailing-slash/index.js @@ -0,0 +1 @@ +import './style.css'; diff --git a/test/cases/publicpath-trailing-slash/react.svg b/test/cases/publicpath-trailing-slash/react.svg new file mode 100644 index 00000000..5b3b22a4 --- /dev/null +++ b/test/cases/publicpath-trailing-slash/react.svg @@ -0,0 +1 @@ +logo-on-dark-bg \ No newline at end of file diff --git a/test/cases/publicpath-trailing-slash/style.css b/test/cases/publicpath-trailing-slash/style.css new file mode 100644 index 00000000..edcbc24a --- /dev/null +++ b/test/cases/publicpath-trailing-slash/style.css @@ -0,0 +1 @@ +body { background: red; background-image: url(./react.svg); } diff --git a/test/cases/publicpath-trailing-slash/webpack.config.js b/test/cases/publicpath-trailing-slash/webpack.config.js new file mode 100644 index 00000000..32180f0d --- /dev/null +++ b/test/cases/publicpath-trailing-slash/webpack.config.js @@ -0,0 +1,34 @@ +const Self = require('../../../'); + +module.exports = { + entry: './index.js', + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + options: { + publicPath: '/static/img' + } + }, + 'css-loader', + ], + }, { + test: /\.(svg|png)$/, + use: [{ + loader: 'file-loader', + options: { + filename: '[name].[ext]' + } + }] + } + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +}; From 6e6642a4cccddf398045d0f262ab30559552a214 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Thu, 13 Dec 2018 18:00:57 +0300 Subject: [PATCH 04/30] feat(hmr): adding hot module reloading Initial implementation copied over from extract-css-chunks-webpack-plugin Adding Eslint config for loaders that are injected directly into the browser. These should remain ES5 --- package.json | 4 +- src/hmr/.eslintrc.js | 23 ++++++ src/hmr/hotLoader.js | 33 ++++++++ src/hmr/hotModuleReplacement.js | 142 ++++++++++++++++++++++++++++++++ src/index.js | 102 +++++++++++++++++++++++ 5 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 src/hmr/.eslintrc.js create mode 100644 src/hmr/hotLoader.js create mode 100644 src/hmr/hotModuleReplacement.js diff --git a/package.json b/package.json index 0d4f3dac..7d009b74 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,9 @@ "webpack": "^4.4.0" }, "dependencies": { - "schema-utils": "^1.0.0", "loader-utils": "^1.1.0", + "normalize-url": "^4.1.0", + "schema-utils": "^1.0.0", "webpack-sources": "^1.1.0" }, "devDependencies": { @@ -62,6 +63,7 @@ "del": "^3.0.0", "del-cli": "^1.1.0", "eslint": "^4.17.0", + "eslint-plugin-compat": "^2.6.3", "eslint-plugin-import": "^2.8.0", "eslint-plugin-prettier": "^2.6.0", "file-loader": "^1.1.11", diff --git a/src/hmr/.eslintrc.js b/src/hmr/.eslintrc.js new file mode 100644 index 00000000..97ca3a15 --- /dev/null +++ b/src/hmr/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + "parserOptions": { + "ecmaVersion": 5, + "sourceType": "module", + }, + globals: { + document: true + }, + plugins: ['prettier'], + extends: ['@webpack-contrib/eslint-config-webpack'], + rules: { + 'prettier/prettier': [ + 'error', + {singleQuote: true, trailingComma: 'es5', arrowParens: 'avoid'}, + ], + 'class-methods-use-this': 'off', + 'no-undefined': 'off', + 'func-style': ["error", "declaration", {"allowArrowFunctions": false}], + 'prefer-rest-params': 0, + 'prefer-spread': 0, + 'prefer-destructuring': 0 + }, +}; diff --git a/src/hmr/hotLoader.js b/src/hmr/hotLoader.js new file mode 100644 index 00000000..ef275f40 --- /dev/null +++ b/src/hmr/hotLoader.js @@ -0,0 +1,33 @@ +const path = require('path'); + +const loaderUtils = require('loader-utils'); + +const defaultOptions = { + fileMap: '{fileName}', +}; + +function hotLoader(content) { + this.cacheable(); + const options = Object.assign( + {}, + defaultOptions, + loaderUtils.getOptions(this) + ); + + const accept = options.cssModules + ? '' + : 'module.hot.accept(undefined, cssReload);'; + return `${content} + if(module.hot) { + // ${Date.now()} + var cssReload = require(${loaderUtils.stringifyRequest( + this, + path.join(__dirname, 'hotModuleReplacement.js') + )})(module.id, ${JSON.stringify(options)}); + module.hot.dispose(cssReload); + ${accept}; + } + `; +} + +module.exports = hotLoader; diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js new file mode 100644 index 00000000..9a257d9c --- /dev/null +++ b/src/hmr/hotModuleReplacement.js @@ -0,0 +1,142 @@ +const normalizeUrl = require('normalize-url'); + +const srcByModuleId = Object.create(null); + +const noDocument = typeof document === 'undefined'; + +function debounce(fn, time) { + let timeout; + + // eslint-disable-next-line func-names + return function() { + const functionCall = () => fn.apply(this, arguments); + + clearTimeout(timeout); + timeout = setTimeout(functionCall, time); + }; +} + +const forEach = Array.prototype.forEach; + +function noop() {} + +function getCurrentScriptUrl(moduleId) { + let src = srcByModuleId[moduleId]; + + if (!src) { + if (document.currentScript) { + src = document.currentScript.src; + } else { + const scripts = document.getElementsByTagName('script'); + const lastScriptTag = scripts[scripts.length - 1]; + + if (lastScriptTag) { + src = lastScriptTag.src; + } + } + srcByModuleId[moduleId] = src; + } + + return function(fileMap) { + const splitResult = /([^\\/]+)\.js$/.exec(src); + const filename = splitResult && splitResult[1]; + if (!filename) { + return [src.replace('.js', '.css')]; + } + return fileMap.split(',').map(mapRule => { + const reg = new RegExp(`${filename}\\.js$`, 'g'); + return normalizeUrl( + src.replace(reg, `${mapRule.replace(/{fileName}/g, filename)}.css`), + { stripWWW: false } + ); + }); + }; +} + +function updateCss(el, url) { + if (!url) { + url = el.href.split('?')[0]; + } + if (el.isLoaded === false) { + // We seem to be about to replace a css link that hasn't loaded yet. + // We're probably changing the same file more than once. + return; + } + if (!url || !(url.indexOf('.css') > -1)) return; + + el.visited = true; + const newEl = el.cloneNode(); + + newEl.isLoaded = false; + + newEl.addEventListener('load', () => { + newEl.isLoaded = true; + el.parentNode.removeChild(el); + }); + + newEl.addEventListener('error', () => { + newEl.isLoaded = true; + el.parentNode.removeChild(el); + }); + + newEl.href = `${url}?${Date.now()}`; + el.parentNode.appendChild(newEl); +} + +function getReloadUrl(href, src) { + href = normalizeUrl(href, { stripWWW: false }); + let ret; + // eslint-disable-next-line array-callback-return + src.some(url => { + if (href.indexOf(src) > -1) { + ret = url; + } + }); + return ret; +} + +function reloadStyle(src) { + const elements = document.querySelectorAll('link'); + let loaded = false; + + forEach.call(elements, el => { + if (el.visited === true) return; + + const url = getReloadUrl(el.href, src); + if (url) { + updateCss(el, url); + loaded = true; + } + }); + + return loaded; +} + +function reloadAll() { + const elements = document.querySelectorAll('link'); + forEach.call(elements, el => { + if (el.visited === true) return; + updateCss(el); + }); +} + +module.exports = function(moduleId, options) { + if (noDocument) { + return noop; + } + + const getScriptSrc = getCurrentScriptUrl(moduleId); + + function update() { + const src = getScriptSrc(options.fileMap); + const reloaded = reloadStyle(src); + if (reloaded && !options.reloadAll) { + console.log('[HMR] css reload %s', src.join(' ')); + } else { + console.log('[HMR] Reload all css'); + reloadAll(); + } + } + + return debounce(update, 10); +}; diff --git a/src/index.js b/src/index.js index c905bb82..aeed1e73 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,10 @@ +import path from 'path'; + import webpack from 'webpack'; import sources from 'webpack-sources'; +const hotLoader = path.resolve(__dirname, './hmr/hotLoader.js'); + const { ConcatSource, SourceMapSource, OriginalSource } = sources; const { Template, @@ -15,6 +19,24 @@ const REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/i; const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i; const REGEXP_NAME = /\[name\]/i; +const isHMR = (compiler) => { + if (compiler && compiler.options) { + if (compiler.options.devServer && compiler.options.devServer.hot) { + return true; + } + + if (compiler.options.entry) { + const entry = + typeof compiler.options.entry === 'function' + ? compiler.options.entry() + : compiler.options.entry; + const entryString = JSON.stringify(entry); + return entryString.includes('hot') || entryString.includes('hmr'); + } + } + return false; +}; + class CssDependency extends webpack.Dependency { constructor( { identifier, content, media, sourceMap }, @@ -116,6 +138,8 @@ class MiniCssExtractPlugin { }, options ); + const { cssModules, reloadAll } = this.options; + if (!this.options.chunkFilename) { const { filename } = this.options; const hasName = filename.includes('[name]'); @@ -132,9 +156,36 @@ class MiniCssExtractPlugin { ); } } + + this.hotLoaderObject = Object.assign( + { + loader: hotLoader, + options: { + cssModules: false, + reloadAll: false, + }, + }, + { + options: { + cssModules, + reloadAll, + }, + } + ); } apply(compiler) { + try { + const isHOT = this.options.hot ? true : isHMR(compiler); + + if (isHOT && compiler.options.module && compiler.options.module.rules) { + compiler.options.module.rules = this.updateWebpackConfig( + compiler.options.module.rules + ); + } + } catch (e) { + throw new Error(`unknown config cannot inject HMR: ${e.stack || e}`); + } compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => { const loaderContext = lc; @@ -394,6 +445,56 @@ class MiniCssExtractPlugin { }); } + traverseDepthFirst(root, visit) { + let nodesToVisit = [root]; + + while (nodesToVisit.length > 0) { + const currentNode = nodesToVisit.shift(); + + if (currentNode !== null && typeof currentNode === 'object') { + const children = Object.values(currentNode); + nodesToVisit = [...children, ...nodesToVisit]; + } + + visit(currentNode); + } + } + + updateWebpackConfig(initialRules) { + return initialRules.reduce((rules, rule) => { + this.traverseDepthFirst(rule, (node) => { + if (node && node.use && Array.isArray(node.use)) { + const isExtractCss = node.use.some((l) => { + const needle = l.loader || l; + if (typeof l === 'function') { + return false; + } + return needle.includes(pluginName); + }); + if (isExtractCss) { + node.use.unshift(this.hotLoaderObject); + } + } + if (node && node.loader && Array.isArray(node.loader)) { + const isExtractCss = node.loader.some((l) => { + const needle = l.loader || l; + if (typeof l === 'function') { + return false; + } + return needle.includes(pluginName); + }); + if (isExtractCss) { + node.loader.unshift(this.hotLoaderObject); + } + } + }); + + rules.push(rule); + + return rules; + }, []); + } + getCssChunkObject(mainChunk) { const obj = {}; for (const chunk of mainChunk.getAllAsyncChunks()) { @@ -547,5 +648,6 @@ class MiniCssExtractPlugin { } MiniCssExtractPlugin.loader = require.resolve('./loader'); +MiniCssExtractPlugin.hotLoader = require.resolve('./hmr/hotLoader'); export default MiniCssExtractPlugin; From 5a9fc854bcef960f950e17c6eb051312b1dfe6c5 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 6 Jan 2019 00:16:08 -0800 Subject: [PATCH 05/30] fix: remove unused dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 7d009b74..079f7472 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,6 @@ "del": "^3.0.0", "del-cli": "^1.1.0", "eslint": "^4.17.0", - "eslint-plugin-compat": "^2.6.3", "eslint-plugin-import": "^2.8.0", "eslint-plugin-prettier": "^2.6.0", "file-loader": "^1.1.11", From 50144a7105861ba3497ae142a344e815f34be321 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 13 Jan 2019 10:49:23 -0800 Subject: [PATCH 06/30] refactor: refactors based on PR comments - Remove `this.cacheable` from hotLoader function - Remove `isHMR`, simplifying codebase - Adding `.idea` to gitignore. This prevents JetBrains products config files --- .gitignore | 1 + src/hmr/hotLoader.js | 9 +++------ src/index.js | 20 +------------------- 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index b70b127e..cb2a818c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ Thumbs.db .vscode *.sublime-project *.sublime-workspace +.idea diff --git a/src/hmr/hotLoader.js b/src/hmr/hotLoader.js index ef275f40..54cb041e 100644 --- a/src/hmr/hotLoader.js +++ b/src/hmr/hotLoader.js @@ -2,15 +2,12 @@ const path = require('path'); const loaderUtils = require('loader-utils'); -const defaultOptions = { - fileMap: '{fileName}', -}; - function hotLoader(content) { - this.cacheable(); const options = Object.assign( {}, - defaultOptions, + { + fileMap: '{fileName}', + }, loaderUtils.getOptions(this) ); diff --git a/src/index.js b/src/index.js index aeed1e73..d9d539f2 100644 --- a/src/index.js +++ b/src/index.js @@ -19,24 +19,6 @@ const REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/i; const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i; const REGEXP_NAME = /\[name\]/i; -const isHMR = (compiler) => { - if (compiler && compiler.options) { - if (compiler.options.devServer && compiler.options.devServer.hot) { - return true; - } - - if (compiler.options.entry) { - const entry = - typeof compiler.options.entry === 'function' - ? compiler.options.entry() - : compiler.options.entry; - const entryString = JSON.stringify(entry); - return entryString.includes('hot') || entryString.includes('hmr'); - } - } - return false; -}; - class CssDependency extends webpack.Dependency { constructor( { identifier, content, media, sourceMap }, @@ -176,7 +158,7 @@ class MiniCssExtractPlugin { apply(compiler) { try { - const isHOT = this.options.hot ? true : isHMR(compiler); + const isHOT = this.options.hot; if (isHOT && compiler.options.module && compiler.options.module.rules) { compiler.options.module.rules = this.updateWebpackConfig( From 39dd711aa22929f9d5c594e792dd908a27325529 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 13 Jan 2019 12:46:50 -0800 Subject: [PATCH 07/30] refactor: move hot loader into base loader Migration of hotLoader from its own file, which is injected into webpack config. Into the base loader of mini-css, instead of adding options to the plugin. Add options to the loader. --- src/hmr/hotLoader.js | 30 --------------- src/hmr/hotModuleReplacement.js | 2 +- src/index.js | 68 --------------------------------- src/loader.js | 25 +++++++++++- 4 files changed, 25 insertions(+), 100 deletions(-) delete mode 100644 src/hmr/hotLoader.js diff --git a/src/hmr/hotLoader.js b/src/hmr/hotLoader.js deleted file mode 100644 index 54cb041e..00000000 --- a/src/hmr/hotLoader.js +++ /dev/null @@ -1,30 +0,0 @@ -const path = require('path'); - -const loaderUtils = require('loader-utils'); - -function hotLoader(content) { - const options = Object.assign( - {}, - { - fileMap: '{fileName}', - }, - loaderUtils.getOptions(this) - ); - - const accept = options.cssModules - ? '' - : 'module.hot.accept(undefined, cssReload);'; - return `${content} - if(module.hot) { - // ${Date.now()} - var cssReload = require(${loaderUtils.stringifyRequest( - this, - path.join(__dirname, 'hotModuleReplacement.js') - )})(module.id, ${JSON.stringify(options)}); - module.hot.dispose(cssReload); - ${accept}; - } - `; -} - -module.exports = hotLoader; diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 9a257d9c..43d75286 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -128,7 +128,7 @@ module.exports = function(moduleId, options) { const getScriptSrc = getCurrentScriptUrl(moduleId); function update() { - const src = getScriptSrc(options.fileMap); + const src = getScriptSrc(options.filename); const reloaded = reloadStyle(src); if (reloaded && !options.reloadAll) { console.log('[HMR] css reload %s', src.join(' ')); diff --git a/src/index.js b/src/index.js index d9d539f2..6e9db066 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,6 @@ -import path from 'path'; - import webpack from 'webpack'; import sources from 'webpack-sources'; -const hotLoader = path.resolve(__dirname, './hmr/hotLoader.js'); - const { ConcatSource, SourceMapSource, OriginalSource } = sources; const { Template, @@ -120,7 +116,6 @@ class MiniCssExtractPlugin { }, options ); - const { cssModules, reloadAll } = this.options; if (!this.options.chunkFilename) { const { filename } = this.options; @@ -138,36 +133,9 @@ class MiniCssExtractPlugin { ); } } - - this.hotLoaderObject = Object.assign( - { - loader: hotLoader, - options: { - cssModules: false, - reloadAll: false, - }, - }, - { - options: { - cssModules, - reloadAll, - }, - } - ); } apply(compiler) { - try { - const isHOT = this.options.hot; - - if (isHOT && compiler.options.module && compiler.options.module.rules) { - compiler.options.module.rules = this.updateWebpackConfig( - compiler.options.module.rules - ); - } - } catch (e) { - throw new Error(`unknown config cannot inject HMR: ${e.stack || e}`); - } compiler.hooks.thisCompilation.tap(pluginName, (compilation) => { compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => { const loaderContext = lc; @@ -442,41 +410,6 @@ class MiniCssExtractPlugin { } } - updateWebpackConfig(initialRules) { - return initialRules.reduce((rules, rule) => { - this.traverseDepthFirst(rule, (node) => { - if (node && node.use && Array.isArray(node.use)) { - const isExtractCss = node.use.some((l) => { - const needle = l.loader || l; - if (typeof l === 'function') { - return false; - } - return needle.includes(pluginName); - }); - if (isExtractCss) { - node.use.unshift(this.hotLoaderObject); - } - } - if (node && node.loader && Array.isArray(node.loader)) { - const isExtractCss = node.loader.some((l) => { - const needle = l.loader || l; - if (typeof l === 'function') { - return false; - } - return needle.includes(pluginName); - }); - if (isExtractCss) { - node.loader.unshift(this.hotLoaderObject); - } - } - }); - - rules.push(rule); - - return rules; - }, []); - } - getCssChunkObject(mainChunk) { const obj = {}; for (const chunk of mainChunk.getAllAsyncChunks()) { @@ -630,6 +563,5 @@ class MiniCssExtractPlugin { } MiniCssExtractPlugin.loader = require.resolve('./loader'); -MiniCssExtractPlugin.hotLoader = require.resolve('./hmr/hotLoader'); export default MiniCssExtractPlugin; diff --git a/src/loader.js b/src/loader.js index 5eafa7ab..b0f2cf0c 100644 --- a/src/loader.js +++ b/src/loader.js @@ -1,5 +1,7 @@ import NativeModule from 'module'; +import path from 'path'; + import loaderUtils from 'loader-utils'; import NodeTemplatePlugin from 'webpack/lib/node/NodeTemplatePlugin'; import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin'; @@ -13,6 +15,24 @@ import schema from './options.json'; const MODULE_TYPE = 'css/mini-extract'; const pluginName = 'mini-css-extract-plugin'; +function hotLoader(content, context) { + const accept = context.modules + ? '' + : 'module.hot.accept(undefined, cssReload);'; + const result = `${content} + if(module.hot) { + // ${Date.now()} + var cssReload = require(${loaderUtils.stringifyRequest( + context.context, + path.join(__dirname, 'hmr/hotModuleReplacement.js') + )})(module.id, ${JSON.stringify(context.query)}); + module.hot.dispose(cssReload); + ${accept} + } + `; + return result; +} + const exec = (loaderContext, code, filename) => { const module = new NativeModule(filename, loaderContext); module.paths = NativeModule._nodeModulePaths(loaderContext.context); // eslint-disable-line no-underscore-dangle @@ -126,6 +146,7 @@ export function pitch(request) { } else { text = text.map((line) => { const module = findModuleById(compilation.modules, line[0]); + return { identifier: module.identifier(), content: line[1], @@ -140,10 +161,12 @@ export function pitch(request) { } let resultSource = `// extracted by ${pluginName}`; if (locals && typeof resultSource !== 'undefined') { - resultSource += `\nmodule.exports = ${JSON.stringify(locals)};`; + const result = `\nmodule.exports = ${JSON.stringify(locals)};`; + resultSource += hotLoader(result, { context: this.context, query }); } return callback(null, resultSource); }); } + export default function() {} From 6126e7ea643b238553249838bef2482379d8be3b Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 23 Jan 2019 20:17:47 -0800 Subject: [PATCH 08/30] refactor: get hmr working with new context String replace based on filename coming in --- src/hmr/hotModuleReplacement.js | 8 +++++++- src/index.js | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 43d75286..652102af 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -38,11 +38,17 @@ function getCurrentScriptUrl(moduleId) { } return function(fileMap) { - const splitResult = /([^\\/]+)\.js$/.exec(src); + if (!src) { + return null; + } + const splitResult = src.split(/([^\\/]+)\.js$/); const filename = splitResult && splitResult[1]; if (!filename) { return [src.replace('.js', '.css')]; } + if (!fileMap) { + return [src.replace('.js', '.css')]; + } return fileMap.split(',').map(mapRule => { const reg = new RegExp(`${filename}\\.js$`, 'g'); return normalizeUrl( diff --git a/src/index.js b/src/index.js index 6e9db066..34e4f3be 100644 --- a/src/index.js +++ b/src/index.js @@ -110,6 +110,7 @@ class CssModuleFactory { class MiniCssExtractPlugin { constructor(options) { + console.log('options', options); this.options = Object.assign( { filename: '[name].css', From cd6df8e6ab593c4650ce8cd1c88a57170fcd688e Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 13:25:32 -0800 Subject: [PATCH 09/30] test: added hmr test case updating js hash and adding hmr test cases --- package.json | 26 +- src/hmr/.eslintrc.js | 23 -- src/hmr/hotModuleReplacement.js | 72 +++-- test/cases/hmr/a.css | 1 + test/cases/hmr/b.css | 5 + test/cases/hmr/c.css | 5 + test/cases/hmr/expected/main.css | 14 + test/cases/hmr/index.css | 2 + test/cases/hmr/webpack.config.js | 28 ++ .../expected/main.52d8306d460bb8ad1388.js | 253 ++++++++++++++++++ .../expected/main.73e85e9f40154bbb5412.js | 253 ++++++++++++++++++ ...6e1512072d65b9db.c747f8a6eecaeef208b9.css} | 0 ...f0222.js => style.74b98ee6c7507ed560f7.js} | 2 + ...674590ef68e758b3.da149d34018298af23b9.css} | 0 .../expected/style.c335d5d236ba55a3fbff.js | 12 + 15 files changed, 632 insertions(+), 64 deletions(-) delete mode 100644 src/hmr/.eslintrc.js create mode 100644 test/cases/hmr/a.css create mode 100644 test/cases/hmr/b.css create mode 100644 test/cases/hmr/c.css create mode 100644 test/cases/hmr/expected/main.css create mode 100644 test/cases/hmr/index.css create mode 100644 test/cases/hmr/webpack.config.js create mode 100644 test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js create mode 100644 test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js rename test/cases/js-hash/expected/{style.11a76e1512072d65b9db.35ee3780b5b76904cef5.css => style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css} (100%) rename test/cases/js-hash/expected/{style.25d094fb4a6ef6ef0222.js => style.74b98ee6c7507ed560f7.js} (85%) rename test/cases/js-hash/expected/{style.822a674590ef68e758b3.ca7d26e87c697b1c7039.css => style.822a674590ef68e758b3.da149d34018298af23b9.css} (100%) create mode 100644 test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js diff --git a/package.json b/package.json index 079f7472..ee2af3d5 100644 --- a/package.json +++ b/package.json @@ -56,27 +56,27 @@ "babel-jest": "^22.2.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-polyfill": "^6.26.0", - "babel-preset-env": "^1.6.1", + "babel-preset-env": "^1.7.0", "conventional-github-releaser": "^2.0.2", - "cross-env": "^5.1.3", - "css-loader": "^0.28.10", + "cross-env": "^5.2.0", + "css-loader": "^2.1.0", "del": "^3.0.0", "del-cli": "^1.1.0", "eslint": "^4.17.0", - "eslint-plugin-import": "^2.8.0", - "eslint-plugin-prettier": "^2.6.0", - "file-loader": "^1.1.11", - "husky": "^0.14.3", + "eslint-plugin-import": "^2.15.0", + "eslint-plugin-prettier": "^3.0.1", + "file-loader": "^3.0.1", + "husky": "^1.3.1", "jest": "^22.2.2", "lint-staged": "^6.1.0", "memory-fs": "^0.4.1", "pre-commit": "^1.2.2", - "prettier": "^1.11.1", - "standard-version": "^4.3.0", - "webpack": "^4.14.0", - "webpack-cli": "^2.0.13", - "webpack-defaults": "^2.3.0", - "webpack-dev-server": "^3.1.1" + "prettier": "^1.16.1", + "standard-version": "^4.4.0", + "webpack": "^4.29.0", + "webpack-cli": "^3.2.1", + "webpack-defaults": "^3.0.0", + "webpack-dev-server": "^3.1.14" }, "keywords": [ "webpack" diff --git a/src/hmr/.eslintrc.js b/src/hmr/.eslintrc.js deleted file mode 100644 index 97ca3a15..00000000 --- a/src/hmr/.eslintrc.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - "parserOptions": { - "ecmaVersion": 5, - "sourceType": "module", - }, - globals: { - document: true - }, - plugins: ['prettier'], - extends: ['@webpack-contrib/eslint-config-webpack'], - rules: { - 'prettier/prettier': [ - 'error', - {singleQuote: true, trailingComma: 'es5', arrowParens: 'avoid'}, - ], - 'class-methods-use-this': 'off', - 'no-undefined': 'off', - 'func-style': ["error", "declaration", {"allowArrowFunctions": false}], - 'prefer-rest-params': 0, - 'prefer-spread': 0, - 'prefer-destructuring': 0 - }, -}; diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 652102af..934742bc 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -1,34 +1,48 @@ -const normalizeUrl = require('normalize-url'); +/* global document, window */ +/* eslint func-names: 0 */ +/* eslint no-var: 0 */ +/* eslint vars-on-top: 0 */ +/* eslint prefer-arrow-func: 0 */ +/* eslint prefer-rest-params: 0 */ +/* eslint prefer-arrow-callback: 0 */ -const srcByModuleId = Object.create(null); +var normalizeUrl = require('normalize-url'); -const noDocument = typeof document === 'undefined'; +var srcByModuleId = Object.create(null); + +var noDocument = typeof document === 'undefined'; + +var forEach = Array.prototype.forEach; function debounce(fn, time) { - let timeout; + var timeout = 0; // eslint-disable-next-line func-names return function() { - const functionCall = () => fn.apply(this, arguments); + var self = this; + var args = arguments; + + // eslint-disable-next-line prefer-rest-params + var functionCall = function functionCall() { + return fn.apply(self, args); + }; clearTimeout(timeout); timeout = setTimeout(functionCall, time); }; } -const forEach = Array.prototype.forEach; - function noop() {} function getCurrentScriptUrl(moduleId) { - let src = srcByModuleId[moduleId]; + var src = srcByModuleId[moduleId]; if (!src) { if (document.currentScript) { src = document.currentScript.src; } else { - const scripts = document.getElementsByTagName('script'); - const lastScriptTag = scripts[scripts.length - 1]; + var scripts = document.getElementsByTagName('script'); + var lastScriptTag = scripts[scripts.length - 1]; if (lastScriptTag) { src = lastScriptTag.src; @@ -41,16 +55,16 @@ function getCurrentScriptUrl(moduleId) { if (!src) { return null; } - const splitResult = src.split(/([^\\/]+)\.js$/); - const filename = splitResult && splitResult[1]; + var splitResult = src.split(/([^\\/]+)\.js$/); + var filename = splitResult && splitResult[1]; if (!filename) { return [src.replace('.js', '.css')]; } if (!fileMap) { return [src.replace('.js', '.css')]; } - return fileMap.split(',').map(mapRule => { - const reg = new RegExp(`${filename}\\.js$`, 'g'); + return fileMap.split(',').map(function(mapRule) { + var reg = new RegExp(`${filename}\\.js$`, 'g'); return normalizeUrl( src.replace(reg, `${mapRule.replace(/{fileName}/g, filename)}.css`), { stripWWW: false } @@ -71,16 +85,16 @@ function updateCss(el, url) { if (!url || !(url.indexOf('.css') > -1)) return; el.visited = true; - const newEl = el.cloneNode(); + var newEl = el.cloneNode(); // eslint-disable-line vars-on-top newEl.isLoaded = false; - newEl.addEventListener('load', () => { + newEl.addEventListener('load', function() { newEl.isLoaded = true; el.parentNode.removeChild(el); }); - newEl.addEventListener('error', () => { + newEl.addEventListener('error', function() { newEl.isLoaded = true; el.parentNode.removeChild(el); }); @@ -90,10 +104,10 @@ function updateCss(el, url) { } function getReloadUrl(href, src) { + var ret; href = normalizeUrl(href, { stripWWW: false }); - let ret; // eslint-disable-next-line array-callback-return - src.some(url => { + src.some(function(url) { if (href.indexOf(src) > -1) { ret = url; } @@ -102,13 +116,14 @@ function getReloadUrl(href, src) { } function reloadStyle(src) { - const elements = document.querySelectorAll('link'); - let loaded = false; + var elements = document.querySelectorAll('link'); + var loaded = false; + + forEach.call(elements, function(el) { + var url = getReloadUrl(el.href, src); - forEach.call(elements, el => { if (el.visited === true) return; - const url = getReloadUrl(el.href, src); if (url) { updateCss(el, url); loaded = true; @@ -119,8 +134,8 @@ function reloadStyle(src) { } function reloadAll() { - const elements = document.querySelectorAll('link'); - forEach.call(elements, el => { + var elements = document.querySelectorAll('link'); + forEach.call(elements, function(el) { if (el.visited === true) return; updateCss(el); }); @@ -131,11 +146,12 @@ module.exports = function(moduleId, options) { return noop; } - const getScriptSrc = getCurrentScriptUrl(moduleId); + // eslint-disable-next-line vars-on-top + var getScriptSrc = getCurrentScriptUrl(moduleId); function update() { - const src = getScriptSrc(options.filename); - const reloaded = reloadStyle(src); + var src = getScriptSrc(options.filename); + var reloaded = reloadStyle(src); if (reloaded && !options.reloadAll) { console.log('[HMR] css reload %s', src.join(' ')); } else { diff --git a/test/cases/hmr/a.css b/test/cases/hmr/a.css new file mode 100644 index 00000000..31fc5b8a --- /dev/null +++ b/test/cases/hmr/a.css @@ -0,0 +1 @@ +body { background: red; } diff --git a/test/cases/hmr/b.css b/test/cases/hmr/b.css new file mode 100644 index 00000000..11559583 --- /dev/null +++ b/test/cases/hmr/b.css @@ -0,0 +1,5 @@ +.b { background: red; } + +@import url("https://some/external/css"); + +.b { color: yellow; } diff --git a/test/cases/hmr/c.css b/test/cases/hmr/c.css new file mode 100644 index 00000000..9c41dd1f --- /dev/null +++ b/test/cases/hmr/c.css @@ -0,0 +1,5 @@ +.c { background: red; } +@import './a.css'; +@import url("https://some/other/external/css"); + +.c { color: yellow; } diff --git a/test/cases/hmr/expected/main.css b/test/cases/hmr/expected/main.css new file mode 100644 index 00000000..cd5dacee --- /dev/null +++ b/test/cases/hmr/expected/main.css @@ -0,0 +1,14 @@ +@import url(https://some/other/external/css); +@import url(https://some/external/css); +body { background: red; } + +.c { background: red; } + +.c { color: yellow; } + +.b { background: red; } + +.b { color: yellow; } + + + diff --git a/test/cases/hmr/index.css b/test/cases/hmr/index.css new file mode 100644 index 00000000..c03e069d --- /dev/null +++ b/test/cases/hmr/index.css @@ -0,0 +1,2 @@ +@import './c.css'; +@import './b.css'; diff --git a/test/cases/hmr/webpack.config.js b/test/cases/hmr/webpack.config.js new file mode 100644 index 00000000..aa6fcb8d --- /dev/null +++ b/test/cases/hmr/webpack.config.js @@ -0,0 +1,28 @@ +const Self = require('../../../'); + +module.exports = { + entry: './index.css', + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: Self.loader, + options: { + hmr: true, + modules: true, + reloadAll: true + }, + }, + 'css-loader', + ], + }, + ], + }, + plugins: [ + new Self({ + filename: '[name].css', + }), + ], +}; diff --git a/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js b/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js new file mode 100644 index 00000000..802b62bd --- /dev/null +++ b/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js @@ -0,0 +1,253 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ }; +/******/ +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded CSS chunks +/******/ var installedCssChunks = { +/******/ 0: 0 +/******/ } +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 0: 0 +/******/ }; +/******/ +/******/ +/******/ +/******/ // script path function +/******/ function jsonpScriptSrc(chunkId) { +/******/ return __webpack_require__.p + "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"c335d5d236ba55a3fbff"}[chunkId] + ".js" +/******/ } +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ var promises = []; +/******/ +/******/ +/******/ // mini-css-extract-plugin CSS loading +/******/ var cssChunks = {"1":1}; +/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]); +/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) { +/******/ promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) { +/******/ var href = "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"822a674590ef68e758b3"}[chunkId] + "." + {"1":"da149d34018298af23b9"}[chunkId] + ".css"; +/******/ var fullhref = __webpack_require__.p + href; +/******/ var existingLinkTags = document.getElementsByTagName("link"); +/******/ for(var i = 0; i < existingLinkTags.length; i++) { +/******/ var tag = existingLinkTags[i]; +/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href"); +/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve(); +/******/ } +/******/ var existingStyleTags = document.getElementsByTagName("style"); +/******/ for(var i = 0; i < existingStyleTags.length; i++) { +/******/ var tag = existingStyleTags[i]; +/******/ var dataHref = tag.getAttribute("data-href"); +/******/ if(dataHref === href || dataHref === fullhref) return resolve(); +/******/ } +/******/ var linkTag = document.createElement("link"); +/******/ linkTag.rel = "stylesheet"; +/******/ linkTag.type = "text/css"; +/******/ linkTag.onload = resolve; +/******/ linkTag.onerror = function(event) { +/******/ var request = event && event.target && event.target.src || fullhref; +/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")"); +/******/ err.request = request; +/******/ delete installedCssChunks[chunkId] +/******/ linkTag.parentNode.removeChild(linkTag) +/******/ reject(err); +/******/ }; +/******/ linkTag.href = fullhref; +/******/ +/******/ var head = document.getElementsByTagName("head")[0]; +/******/ head.appendChild(linkTag); +/******/ }).then(function() { +/******/ installedCssChunks[chunkId] = 0; +/******/ })); +/******/ } +/******/ +/******/ // JSONP chunk loading for javascript +/******/ +/******/ var installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var head = document.getElementsByTagName('head')[0]; +/******/ var script = document.createElement('script'); +/******/ var onScriptComplete; +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = jsonpScriptSrc(chunkId); +/******/ +/******/ onScriptComplete = function (event) { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'); +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ chunk[1](error); +/******/ } +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ var timeout = setTimeout(function(){ +/******/ onScriptComplete({ type: 'timeout', target: script }); +/******/ }, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ head.appendChild(script); +/******/ } +/******/ } +/******/ return Promise.all(promises); +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__.e(/* import() | style */ 1).then(__webpack_require__.t.bind(null, 1, 7)); + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js b/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js new file mode 100644 index 00000000..a6efa2bd --- /dev/null +++ b/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js @@ -0,0 +1,253 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ }; +/******/ +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded CSS chunks +/******/ var installedCssChunks = { +/******/ 0: 0 +/******/ } +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 0: 0 +/******/ }; +/******/ +/******/ +/******/ +/******/ // script path function +/******/ function jsonpScriptSrc(chunkId) { +/******/ return __webpack_require__.p + "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"74b98ee6c7507ed560f7"}[chunkId] + ".js" +/******/ } +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = function requireEnsure(chunkId) { +/******/ var promises = []; +/******/ +/******/ +/******/ // mini-css-extract-plugin CSS loading +/******/ var cssChunks = {"1":1}; +/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]); +/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) { +/******/ promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) { +/******/ var href = "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"11a76e1512072d65b9db"}[chunkId] + "." + {"1":"c747f8a6eecaeef208b9"}[chunkId] + ".css"; +/******/ var fullhref = __webpack_require__.p + href; +/******/ var existingLinkTags = document.getElementsByTagName("link"); +/******/ for(var i = 0; i < existingLinkTags.length; i++) { +/******/ var tag = existingLinkTags[i]; +/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href"); +/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve(); +/******/ } +/******/ var existingStyleTags = document.getElementsByTagName("style"); +/******/ for(var i = 0; i < existingStyleTags.length; i++) { +/******/ var tag = existingStyleTags[i]; +/******/ var dataHref = tag.getAttribute("data-href"); +/******/ if(dataHref === href || dataHref === fullhref) return resolve(); +/******/ } +/******/ var linkTag = document.createElement("link"); +/******/ linkTag.rel = "stylesheet"; +/******/ linkTag.type = "text/css"; +/******/ linkTag.onload = resolve; +/******/ linkTag.onerror = function(event) { +/******/ var request = event && event.target && event.target.src || fullhref; +/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")"); +/******/ err.request = request; +/******/ delete installedCssChunks[chunkId] +/******/ linkTag.parentNode.removeChild(linkTag) +/******/ reject(err); +/******/ }; +/******/ linkTag.href = fullhref; +/******/ +/******/ var head = document.getElementsByTagName("head")[0]; +/******/ head.appendChild(linkTag); +/******/ }).then(function() { +/******/ installedCssChunks[chunkId] = 0; +/******/ })); +/******/ } +/******/ +/******/ // JSONP chunk loading for javascript +/******/ +/******/ var installedChunkData = installedChunks[chunkId]; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[2]); +/******/ } else { +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ promises.push(installedChunkData[2] = promise); +/******/ +/******/ // start chunk loading +/******/ var head = document.getElementsByTagName('head')[0]; +/******/ var script = document.createElement('script'); +/******/ var onScriptComplete; +/******/ +/******/ script.charset = 'utf-8'; +/******/ script.timeout = 120; +/******/ if (__webpack_require__.nc) { +/******/ script.setAttribute("nonce", __webpack_require__.nc); +/******/ } +/******/ script.src = jsonpScriptSrc(chunkId); +/******/ +/******/ onScriptComplete = function (event) { +/******/ // avoid mem leaks in IE. +/******/ script.onerror = script.onload = null; +/******/ clearTimeout(timeout); +/******/ var chunk = installedChunks[chunkId]; +/******/ if(chunk !== 0) { +/******/ if(chunk) { +/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); +/******/ var realSrc = event && event.target && event.target.src; +/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'); +/******/ error.type = errorType; +/******/ error.request = realSrc; +/******/ chunk[1](error); +/******/ } +/******/ installedChunks[chunkId] = undefined; +/******/ } +/******/ }; +/******/ var timeout = setTimeout(function(){ +/******/ onScriptComplete({ type: 'timeout', target: script }); +/******/ }, 120000); +/******/ script.onerror = script.onload = onScriptComplete; +/******/ head.appendChild(script); +/******/ } +/******/ } +/******/ return Promise.all(promises); +/******/ }; +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // on error function for async loading +/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; +/******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__.e(/* import() | style */ 1).then(__webpack_require__.t.bind(null, 1, 7)); + + +/***/ }) +/******/ ]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/style.11a76e1512072d65b9db.35ee3780b5b76904cef5.css b/test/cases/js-hash/expected/style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css similarity index 100% rename from test/cases/js-hash/expected/style.11a76e1512072d65b9db.35ee3780b5b76904cef5.css rename to test/cases/js-hash/expected/style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css diff --git a/test/cases/js-hash/expected/style.25d094fb4a6ef6ef0222.js b/test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js similarity index 85% rename from test/cases/js-hash/expected/style.25d094fb4a6ef6ef0222.js rename to test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js index 21f472ef..54ca4d2f 100644 --- a/test/cases/js-hash/expected/style.25d094fb4a6ef6ef0222.js +++ b/test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js @@ -5,6 +5,8 @@ // extracted by mini-css-extract-plugin module.exports = {"a":"wX52cuPepLZcpDx5S3yYO"}; + if(false) { var cssReload; } + /***/ }) ]]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/style.822a674590ef68e758b3.ca7d26e87c697b1c7039.css b/test/cases/js-hash/expected/style.822a674590ef68e758b3.da149d34018298af23b9.css similarity index 100% rename from test/cases/js-hash/expected/style.822a674590ef68e758b3.ca7d26e87c697b1c7039.css rename to test/cases/js-hash/expected/style.822a674590ef68e758b3.da149d34018298af23b9.css diff --git a/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js b/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js new file mode 100644 index 00000000..54ca4d2f --- /dev/null +++ b/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js @@ -0,0 +1,12 @@ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[ +/* 0 */, +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +// extracted by mini-css-extract-plugin +module.exports = {"a":"wX52cuPepLZcpDx5S3yYO"}; + if(false) { var cssReload; } + + +/***/ }) +]]); \ No newline at end of file From bf0f7453efe7ff07030073b1a5c3b2059d951712 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 13:54:16 -0800 Subject: [PATCH 10/30] revert: roll back package upgrades --- package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index ee2af3d5..079f7472 100644 --- a/package.json +++ b/package.json @@ -56,27 +56,27 @@ "babel-jest": "^22.2.2", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-polyfill": "^6.26.0", - "babel-preset-env": "^1.7.0", + "babel-preset-env": "^1.6.1", "conventional-github-releaser": "^2.0.2", - "cross-env": "^5.2.0", - "css-loader": "^2.1.0", + "cross-env": "^5.1.3", + "css-loader": "^0.28.10", "del": "^3.0.0", "del-cli": "^1.1.0", "eslint": "^4.17.0", - "eslint-plugin-import": "^2.15.0", - "eslint-plugin-prettier": "^3.0.1", - "file-loader": "^3.0.1", - "husky": "^1.3.1", + "eslint-plugin-import": "^2.8.0", + "eslint-plugin-prettier": "^2.6.0", + "file-loader": "^1.1.11", + "husky": "^0.14.3", "jest": "^22.2.2", "lint-staged": "^6.1.0", "memory-fs": "^0.4.1", "pre-commit": "^1.2.2", - "prettier": "^1.16.1", - "standard-version": "^4.4.0", - "webpack": "^4.29.0", - "webpack-cli": "^3.2.1", - "webpack-defaults": "^3.0.0", - "webpack-dev-server": "^3.1.14" + "prettier": "^1.11.1", + "standard-version": "^4.3.0", + "webpack": "^4.14.0", + "webpack-cli": "^2.0.13", + "webpack-defaults": "^2.3.0", + "webpack-dev-server": "^3.1.1" }, "keywords": [ "webpack" From d1cbf81942e7626d690a43e1c8d1d16f2a8621ce Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 14:05:46 -0800 Subject: [PATCH 11/30] fix: updating dependencies --- package.json | 2 +- .../expected/main.52d8306d460bb8ad1388.js | 253 ------------------ .../expected/main.73e85e9f40154bbb5412.js | 253 ------------------ ...3b9.css => style.185da89e33584d37fe33.css} | 0 .../expected/style.74b98ee6c7507ed560f7.js | 12 - .../expected/style.c335d5d236ba55a3fbff.js | 12 - ...8b9.css => style.c69d9c57cb899f95ee82.css} | 0 test/cases/js-hash/webpack.config.js | 2 +- 8 files changed, 2 insertions(+), 532 deletions(-) delete mode 100644 test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js delete mode 100644 test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js rename test/cases/js-hash/expected/{style.822a674590ef68e758b3.da149d34018298af23b9.css => style.185da89e33584d37fe33.css} (100%) delete mode 100644 test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js delete mode 100644 test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js rename test/cases/js-hash/expected/{style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css => style.c69d9c57cb899f95ee82.css} (100%) diff --git a/package.json b/package.json index 079f7472..d9a4fd10 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "webpack": "^4.4.0" }, "dependencies": { - "loader-utils": "^1.1.0", + "loader-utils": "^1.2.3", "normalize-url": "^4.1.0", "schema-utils": "^1.0.0", "webpack-sources": "^1.1.0" diff --git a/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js b/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js deleted file mode 100644 index 802b62bd..00000000 --- a/test/cases/js-hash/expected/main.52d8306d460bb8ad1388.js +++ /dev/null @@ -1,253 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // install a JSONP callback for chunk loading -/******/ function webpackJsonpCallback(data) { -/******/ var chunkIds = data[0]; -/******/ var moreModules = data[1]; -/******/ -/******/ -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); -/******/ } -/******/ installedChunks[chunkId] = 0; -/******/ } -/******/ for(moduleId in moreModules) { -/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { -/******/ modules[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(parentJsonpFunction) parentJsonpFunction(data); -/******/ -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ }; -/******/ -/******/ -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // object to store loaded CSS chunks -/******/ var installedCssChunks = { -/******/ 0: 0 -/******/ } -/******/ -/******/ // object to store loaded and loading chunks -/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded -/******/ var installedChunks = { -/******/ 0: 0 -/******/ }; -/******/ -/******/ -/******/ -/******/ // script path function -/******/ function jsonpScriptSrc(chunkId) { -/******/ return __webpack_require__.p + "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"c335d5d236ba55a3fbff"}[chunkId] + ".js" -/******/ } -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ // This file contains only the entry chunk. -/******/ // The chunk loading function for additional chunks -/******/ __webpack_require__.e = function requireEnsure(chunkId) { -/******/ var promises = []; -/******/ -/******/ -/******/ // mini-css-extract-plugin CSS loading -/******/ var cssChunks = {"1":1}; -/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]); -/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) { -/******/ promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) { -/******/ var href = "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"822a674590ef68e758b3"}[chunkId] + "." + {"1":"da149d34018298af23b9"}[chunkId] + ".css"; -/******/ var fullhref = __webpack_require__.p + href; -/******/ var existingLinkTags = document.getElementsByTagName("link"); -/******/ for(var i = 0; i < existingLinkTags.length; i++) { -/******/ var tag = existingLinkTags[i]; -/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href"); -/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve(); -/******/ } -/******/ var existingStyleTags = document.getElementsByTagName("style"); -/******/ for(var i = 0; i < existingStyleTags.length; i++) { -/******/ var tag = existingStyleTags[i]; -/******/ var dataHref = tag.getAttribute("data-href"); -/******/ if(dataHref === href || dataHref === fullhref) return resolve(); -/******/ } -/******/ var linkTag = document.createElement("link"); -/******/ linkTag.rel = "stylesheet"; -/******/ linkTag.type = "text/css"; -/******/ linkTag.onload = resolve; -/******/ linkTag.onerror = function(event) { -/******/ var request = event && event.target && event.target.src || fullhref; -/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")"); -/******/ err.request = request; -/******/ delete installedCssChunks[chunkId] -/******/ linkTag.parentNode.removeChild(linkTag) -/******/ reject(err); -/******/ }; -/******/ linkTag.href = fullhref; -/******/ -/******/ var head = document.getElementsByTagName("head")[0]; -/******/ head.appendChild(linkTag); -/******/ }).then(function() { -/******/ installedCssChunks[chunkId] = 0; -/******/ })); -/******/ } -/******/ -/******/ // JSONP chunk loading for javascript -/******/ -/******/ var installedChunkData = installedChunks[chunkId]; -/******/ if(installedChunkData !== 0) { // 0 means "already installed". -/******/ -/******/ // a Promise means "currently loading". -/******/ if(installedChunkData) { -/******/ promises.push(installedChunkData[2]); -/******/ } else { -/******/ // setup Promise in chunk cache -/******/ var promise = new Promise(function(resolve, reject) { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); -/******/ promises.push(installedChunkData[2] = promise); -/******/ -/******/ // start chunk loading -/******/ var head = document.getElementsByTagName('head')[0]; -/******/ var script = document.createElement('script'); -/******/ var onScriptComplete; -/******/ -/******/ script.charset = 'utf-8'; -/******/ script.timeout = 120; -/******/ if (__webpack_require__.nc) { -/******/ script.setAttribute("nonce", __webpack_require__.nc); -/******/ } -/******/ script.src = jsonpScriptSrc(chunkId); -/******/ -/******/ onScriptComplete = function (event) { -/******/ // avoid mem leaks in IE. -/******/ script.onerror = script.onload = null; -/******/ clearTimeout(timeout); -/******/ var chunk = installedChunks[chunkId]; -/******/ if(chunk !== 0) { -/******/ if(chunk) { -/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); -/******/ var realSrc = event && event.target && event.target.src; -/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'); -/******/ error.type = errorType; -/******/ error.request = realSrc; -/******/ chunk[1](error); -/******/ } -/******/ installedChunks[chunkId] = undefined; -/******/ } -/******/ }; -/******/ var timeout = setTimeout(function(){ -/******/ onScriptComplete({ type: 'timeout', target: script }); -/******/ }, 120000); -/******/ script.onerror = script.onload = onScriptComplete; -/******/ head.appendChild(script); -/******/ } -/******/ } -/******/ return Promise.all(promises); -/******/ }; -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // on error function for async loading -/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; -/******/ -/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; -/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); -/******/ jsonpArray.push = webpackJsonpCallback; -/******/ jsonpArray = jsonpArray.slice(); -/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); -/******/ var parentJsonpFunction = oldJsonpFunction; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -__webpack_require__.e(/* import() | style */ 1).then(__webpack_require__.t.bind(null, 1, 7)); - - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js b/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js deleted file mode 100644 index a6efa2bd..00000000 --- a/test/cases/js-hash/expected/main.73e85e9f40154bbb5412.js +++ /dev/null @@ -1,253 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // install a JSONP callback for chunk loading -/******/ function webpackJsonpCallback(data) { -/******/ var chunkIds = data[0]; -/******/ var moreModules = data[1]; -/******/ -/******/ -/******/ // add "moreModules" to the modules object, -/******/ // then flag all "chunkIds" as loaded and fire callback -/******/ var moduleId, chunkId, i = 0, resolves = []; -/******/ for(;i < chunkIds.length; i++) { -/******/ chunkId = chunkIds[i]; -/******/ if(installedChunks[chunkId]) { -/******/ resolves.push(installedChunks[chunkId][0]); -/******/ } -/******/ installedChunks[chunkId] = 0; -/******/ } -/******/ for(moduleId in moreModules) { -/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { -/******/ modules[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(parentJsonpFunction) parentJsonpFunction(data); -/******/ -/******/ while(resolves.length) { -/******/ resolves.shift()(); -/******/ } -/******/ -/******/ }; -/******/ -/******/ -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // object to store loaded CSS chunks -/******/ var installedCssChunks = { -/******/ 0: 0 -/******/ } -/******/ -/******/ // object to store loaded and loading chunks -/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched -/******/ // Promise = chunk loading, 0 = chunk loaded -/******/ var installedChunks = { -/******/ 0: 0 -/******/ }; -/******/ -/******/ -/******/ -/******/ // script path function -/******/ function jsonpScriptSrc(chunkId) { -/******/ return __webpack_require__.p + "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"74b98ee6c7507ed560f7"}[chunkId] + ".js" -/******/ } -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ // This file contains only the entry chunk. -/******/ // The chunk loading function for additional chunks -/******/ __webpack_require__.e = function requireEnsure(chunkId) { -/******/ var promises = []; -/******/ -/******/ -/******/ // mini-css-extract-plugin CSS loading -/******/ var cssChunks = {"1":1}; -/******/ if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]); -/******/ else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) { -/******/ promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) { -/******/ var href = "" + ({"1":"style"}[chunkId]||chunkId) + "." + {"1":"11a76e1512072d65b9db"}[chunkId] + "." + {"1":"c747f8a6eecaeef208b9"}[chunkId] + ".css"; -/******/ var fullhref = __webpack_require__.p + href; -/******/ var existingLinkTags = document.getElementsByTagName("link"); -/******/ for(var i = 0; i < existingLinkTags.length; i++) { -/******/ var tag = existingLinkTags[i]; -/******/ var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href"); -/******/ if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve(); -/******/ } -/******/ var existingStyleTags = document.getElementsByTagName("style"); -/******/ for(var i = 0; i < existingStyleTags.length; i++) { -/******/ var tag = existingStyleTags[i]; -/******/ var dataHref = tag.getAttribute("data-href"); -/******/ if(dataHref === href || dataHref === fullhref) return resolve(); -/******/ } -/******/ var linkTag = document.createElement("link"); -/******/ linkTag.rel = "stylesheet"; -/******/ linkTag.type = "text/css"; -/******/ linkTag.onload = resolve; -/******/ linkTag.onerror = function(event) { -/******/ var request = event && event.target && event.target.src || fullhref; -/******/ var err = new Error("Loading CSS chunk " + chunkId + " failed.\n(" + request + ")"); -/******/ err.request = request; -/******/ delete installedCssChunks[chunkId] -/******/ linkTag.parentNode.removeChild(linkTag) -/******/ reject(err); -/******/ }; -/******/ linkTag.href = fullhref; -/******/ -/******/ var head = document.getElementsByTagName("head")[0]; -/******/ head.appendChild(linkTag); -/******/ }).then(function() { -/******/ installedCssChunks[chunkId] = 0; -/******/ })); -/******/ } -/******/ -/******/ // JSONP chunk loading for javascript -/******/ -/******/ var installedChunkData = installedChunks[chunkId]; -/******/ if(installedChunkData !== 0) { // 0 means "already installed". -/******/ -/******/ // a Promise means "currently loading". -/******/ if(installedChunkData) { -/******/ promises.push(installedChunkData[2]); -/******/ } else { -/******/ // setup Promise in chunk cache -/******/ var promise = new Promise(function(resolve, reject) { -/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject]; -/******/ }); -/******/ promises.push(installedChunkData[2] = promise); -/******/ -/******/ // start chunk loading -/******/ var head = document.getElementsByTagName('head')[0]; -/******/ var script = document.createElement('script'); -/******/ var onScriptComplete; -/******/ -/******/ script.charset = 'utf-8'; -/******/ script.timeout = 120; -/******/ if (__webpack_require__.nc) { -/******/ script.setAttribute("nonce", __webpack_require__.nc); -/******/ } -/******/ script.src = jsonpScriptSrc(chunkId); -/******/ -/******/ onScriptComplete = function (event) { -/******/ // avoid mem leaks in IE. -/******/ script.onerror = script.onload = null; -/******/ clearTimeout(timeout); -/******/ var chunk = installedChunks[chunkId]; -/******/ if(chunk !== 0) { -/******/ if(chunk) { -/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type); -/******/ var realSrc = event && event.target && event.target.src; -/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'); -/******/ error.type = errorType; -/******/ error.request = realSrc; -/******/ chunk[1](error); -/******/ } -/******/ installedChunks[chunkId] = undefined; -/******/ } -/******/ }; -/******/ var timeout = setTimeout(function(){ -/******/ onScriptComplete({ type: 'timeout', target: script }); -/******/ }, 120000); -/******/ script.onerror = script.onload = onScriptComplete; -/******/ head.appendChild(script); -/******/ } -/******/ } -/******/ return Promise.all(promises); -/******/ }; -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // on error function for async loading -/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; }; -/******/ -/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; -/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); -/******/ jsonpArray.push = webpackJsonpCallback; -/******/ jsonpArray = jsonpArray.slice(); -/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); -/******/ var parentJsonpFunction = oldJsonpFunction; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -__webpack_require__.e(/* import() | style */ 1).then(__webpack_require__.t.bind(null, 1, 7)); - - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/style.822a674590ef68e758b3.da149d34018298af23b9.css b/test/cases/js-hash/expected/style.185da89e33584d37fe33.css similarity index 100% rename from test/cases/js-hash/expected/style.822a674590ef68e758b3.da149d34018298af23b9.css rename to test/cases/js-hash/expected/style.185da89e33584d37fe33.css diff --git a/test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js b/test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js deleted file mode 100644 index 54ca4d2f..00000000 --- a/test/cases/js-hash/expected/style.74b98ee6c7507ed560f7.js +++ /dev/null @@ -1,12 +0,0 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[ -/* 0 */, -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -// extracted by mini-css-extract-plugin -module.exports = {"a":"wX52cuPepLZcpDx5S3yYO"}; - if(false) { var cssReload; } - - -/***/ }) -]]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js b/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js deleted file mode 100644 index 54ca4d2f..00000000 --- a/test/cases/js-hash/expected/style.c335d5d236ba55a3fbff.js +++ /dev/null @@ -1,12 +0,0 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[ -/* 0 */, -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -// extracted by mini-css-extract-plugin -module.exports = {"a":"wX52cuPepLZcpDx5S3yYO"}; - if(false) { var cssReload; } - - -/***/ }) -]]); \ No newline at end of file diff --git a/test/cases/js-hash/expected/style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css b/test/cases/js-hash/expected/style.c69d9c57cb899f95ee82.css similarity index 100% rename from test/cases/js-hash/expected/style.11a76e1512072d65b9db.c747f8a6eecaeef208b9.css rename to test/cases/js-hash/expected/style.c69d9c57cb899f95ee82.css diff --git a/test/cases/js-hash/webpack.config.js b/test/cases/js-hash/webpack.config.js index de241c13..b95dfdbb 100644 --- a/test/cases/js-hash/webpack.config.js +++ b/test/cases/js-hash/webpack.config.js @@ -30,7 +30,7 @@ module.exports = [1, 2].map(n => ({ }, plugins: [ new Self({ - filename: `[name].[contenthash].[chunkhash].css`, + filename: `[name].[chunkhash].css`, }), ], })); From 31bfa7190c850e164b26a24b3bb67705aed14323 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 14:53:38 -0800 Subject: [PATCH 12/30] fix: remove console log --- src/index.js | 1 - test/cases/js-hash/webpack.config.js | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 34e4f3be..6e9db066 100644 --- a/src/index.js +++ b/src/index.js @@ -110,7 +110,6 @@ class CssModuleFactory { class MiniCssExtractPlugin { constructor(options) { - console.log('options', options); this.options = Object.assign( { filename: '[name].css', diff --git a/test/cases/js-hash/webpack.config.js b/test/cases/js-hash/webpack.config.js index b95dfdbb..e9865055 100644 --- a/test/cases/js-hash/webpack.config.js +++ b/test/cases/js-hash/webpack.config.js @@ -7,7 +7,12 @@ module.exports = [1, 2].map(n => ({ { test: /\.css$/, use: [ - Self.loader, + { + loader: Self.loader, + options:{ + hot: false + } + }, { loader: 'css-loader', options: { From a51d862b850d5db755c00003567206a8d8188548 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 15:06:31 -0800 Subject: [PATCH 13/30] test: fixing tests removing hot loader to fix tests --- package-lock.json | 103 +++++------------- package.json | 4 +- ...e82.css => style.9b11dfbd73d90b346d16.css} | 0 ...e33.css => style.b62a24baf4785af5a972.css} | 0 4 files changed, 29 insertions(+), 78 deletions(-) rename test/cases/js-hash/expected/{style.c69d9c57cb899f95ee82.css => style.9b11dfbd73d90b346d16.css} (100%) rename test/cases/js-hash/expected/{style.185da89e33584d37fe33.css => style.b62a24baf4785af5a972.css} (100%) diff --git a/package-lock.json b/package-lock.json index d3a4647e..22bd7f10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5796,7 +5796,6 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", "dev": true, - "optional": true, "requires": { "nan": "^2.9.2", "node-pre-gyp": "^0.10.0" @@ -5805,8 +5804,7 @@ "abbrev": { "version": "1.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ansi-regex": { "version": "2.1.1", @@ -5816,14 +5814,12 @@ "aproba": { "version": "1.2.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "are-we-there-yet": { "version": "1.1.4", "bundled": true, "dev": true, - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -5846,8 +5842,7 @@ "chownr": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "code-point-at": { "version": "1.1.0", @@ -5867,14 +5862,12 @@ "core-util-is": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "debug": { "version": "2.6.9", "bundled": true, "dev": true, - "optional": true, "requires": { "ms": "2.0.0" } @@ -5882,26 +5875,22 @@ "deep-extend": { "version": "0.5.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "delegates": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "detect-libc": { "version": "1.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "fs-minipass": { "version": "1.2.5", "bundled": true, "dev": true, - "optional": true, "requires": { "minipass": "^2.2.1" } @@ -5909,14 +5898,12 @@ "fs.realpath": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "gauge": { "version": "2.7.4", "bundled": true, "dev": true, - "optional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -5932,7 +5919,6 @@ "version": "7.1.2", "bundled": true, "dev": true, - "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5945,14 +5931,12 @@ "has-unicode": { "version": "2.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "iconv-lite": { "version": "0.4.21", "bundled": true, "dev": true, - "optional": true, "requires": { "safer-buffer": "^2.1.0" } @@ -5961,7 +5945,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimatch": "^3.0.4" } @@ -5970,7 +5953,6 @@ "version": "1.0.6", "bundled": true, "dev": true, - "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5984,8 +5966,7 @@ "ini": { "version": "1.3.5", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -5998,8 +5979,7 @@ "isarray": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minimatch": { "version": "3.0.4", @@ -6027,7 +6007,6 @@ "version": "1.1.0", "bundled": true, "dev": true, - "optional": true, "requires": { "minipass": "^2.2.1" } @@ -6043,14 +6022,12 @@ "ms": { "version": "2.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "needle": { "version": "2.2.0", "bundled": true, "dev": true, - "optional": true, "requires": { "debug": "^2.1.2", "iconv-lite": "^0.4.4", @@ -6061,7 +6038,6 @@ "version": "0.10.0", "bundled": true, "dev": true, - "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", @@ -6079,7 +6055,6 @@ "version": "4.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" @@ -6088,14 +6063,12 @@ "npm-bundled": { "version": "1.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "npm-packlist": { "version": "1.1.10", "bundled": true, "dev": true, - "optional": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1" @@ -6105,7 +6078,6 @@ "version": "4.1.2", "bundled": true, "dev": true, - "optional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -6121,8 +6093,7 @@ "object-assign": { "version": "4.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "once": { "version": "1.4.0", @@ -6135,20 +6106,17 @@ "os-homedir": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "os-tmpdir": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "osenv": { "version": "0.1.5", "bundled": true, "dev": true, - "optional": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -6157,20 +6125,17 @@ "path-is-absolute": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "process-nextick-args": { "version": "2.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "rc": { "version": "1.2.7", "bundled": true, "dev": true, - "optional": true, "requires": { "deep-extend": "^0.5.1", "ini": "~1.3.0", @@ -6181,8 +6146,7 @@ "minimist": { "version": "1.2.0", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, @@ -6190,7 +6154,6 @@ "version": "2.3.6", "bundled": true, "dev": true, - "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6205,7 +6168,6 @@ "version": "2.6.2", "bundled": true, "dev": true, - "optional": true, "requires": { "glob": "^7.0.5" } @@ -6218,32 +6180,27 @@ "safer-buffer": { "version": "2.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "sax": { "version": "1.2.4", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "semver": { "version": "5.5.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "set-blocking": { "version": "2.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "signal-exit": { "version": "3.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "string-width": { "version": "1.0.2", @@ -6259,7 +6216,6 @@ "version": "1.1.1", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6275,14 +6231,12 @@ "strip-json-comments": { "version": "2.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "tar": { "version": "4.4.1", "bundled": true, "dev": true, - "optional": true, "requires": { "chownr": "^1.0.1", "fs-minipass": "^1.2.5", @@ -6296,14 +6250,12 @@ "util-deprecate": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "wide-align": { "version": "1.1.2", "bundled": true, "dev": true, - "optional": true, "requires": { "string-width": "^1.0.2" } @@ -9941,8 +9893,7 @@ "version": "2.11.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", - "dev": true, - "optional": true + "dev": true }, "nanomatch": { "version": "1.2.13", diff --git a/package.json b/package.json index d9a4fd10..27749269 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,9 @@ "webpack": "^4.4.0" }, "dependencies": { - "loader-utils": "^1.2.3", - "normalize-url": "^4.1.0", "schema-utils": "^1.0.0", + "normalize-url": "^4.1.0", + "loader-utils": "^1.1.0", "webpack-sources": "^1.1.0" }, "devDependencies": { diff --git a/test/cases/js-hash/expected/style.c69d9c57cb899f95ee82.css b/test/cases/js-hash/expected/style.9b11dfbd73d90b346d16.css similarity index 100% rename from test/cases/js-hash/expected/style.c69d9c57cb899f95ee82.css rename to test/cases/js-hash/expected/style.9b11dfbd73d90b346d16.css diff --git a/test/cases/js-hash/expected/style.185da89e33584d37fe33.css b/test/cases/js-hash/expected/style.b62a24baf4785af5a972.css similarity index 100% rename from test/cases/js-hash/expected/style.185da89e33584d37fe33.css rename to test/cases/js-hash/expected/style.b62a24baf4785af5a972.css From 2bd6661e36a58ef50c36f8e65843d52fe5205f32 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 15:17:25 -0800 Subject: [PATCH 14/30] fix: use older version of normalize using version 3 of normalize-url for node 6 compatibility --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27749269..bf1ff2d5 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "dependencies": { "schema-utils": "^1.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^3.0.0", "loader-utils": "^1.1.0", "webpack-sources": "^1.1.0" }, From 9803db33d323335fd890e7ba4bb5921e28171a87 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 15:27:25 -0800 Subject: [PATCH 15/30] fix: remove vulnerabilities in depencencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf1ff2d5..ceecab67 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "webpack": "^4.14.0", "webpack-cli": "^2.0.13", "webpack-defaults": "^2.3.0", - "webpack-dev-server": "^3.1.1" + "webpack-dev-server": "^3.1.14" }, "keywords": [ "webpack" From c19043654da1aa15024dafcadf095e0cabbd4dd9 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sun, 27 Jan 2019 16:04:50 -0800 Subject: [PATCH 16/30] test: adding snapshot for hmr Adding es-checker to prevent any es6 in the hot loader --- package-lock.json | 452 +++++++++++++++++----- package.json | 5 +- src/hmr/hotModuleReplacement.js | 7 +- test/TestCases.test.js | 22 ++ test/__snapshots__/TestCases.test.js.snap | 170 ++++++++ test/cases/hmr/expected/main.js | 94 +++++ 6 files changed, 648 insertions(+), 102 deletions(-) create mode 100644 test/__snapshots__/TestCases.test.js.snap create mode 100644 test/cases/hmr/expected/main.js diff --git a/package-lock.json b/package-lock.json index 22bd7f10..b8067258 100644 --- a/package-lock.json +++ b/package-lock.json @@ -557,6 +557,11 @@ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "dev": true }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -587,8 +592,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "3.2.1", @@ -637,6 +641,15 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1828,8 +1841,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base": { "version": "0.11.2", @@ -1939,8 +1951,7 @@ "bluebird": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" }, "bn.js": { "version": "4.11.8", @@ -2010,7 +2021,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2182,8 +2192,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-indexof": { "version": "1.1.1", @@ -2404,6 +2413,24 @@ "integrity": "sha512-CAZ9QXGViBvhHnmIHhsTPSWFBujDaelKnUj7wwImbyQRxmXynYqKGi3UaZTSz9MoVh+1EVxOS/DFIkrJYgR3aw==", "dev": true }, + "caporal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/caporal/-/caporal-1.1.0.tgz", + "integrity": "sha512-R5qo2QGoqBM6RvzHonGhUuEJSeqEa4lD1r+cPUEY2+YsXhpQVTS2TvScfIbi6ydFdhzFCNeNUB1v0YrRBvsbdg==", + "requires": { + "bluebird": "^3.4.7", + "cli-table3": "^0.5.0", + "colorette": "1.0.1", + "fast-levenshtein": "^2.0.6", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.merge": "^4.6.0", + "micromist": "1.1.0", + "prettyjson": "^1.2.1", + "tabtab": "^2.2.2", + "winston": "^2.3.1" + } + }, "capture-exit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", @@ -2600,6 +2627,16 @@ } } }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, "cli-truncate": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", @@ -2641,8 +2678,7 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "cliui": { "version": "4.1.0", @@ -2728,8 +2764,7 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collection-visit": { "version": "1.0.0", @@ -2776,6 +2811,11 @@ "color-name": "^1.0.0" } }, + "colorette": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.0.1.tgz", + "integrity": "sha512-40MnlppkzHhFjRhtXunbpqKUT+eJn0gyVGi8aQlNSG8T2CCy31NdD7yktcS0aizH1VP2OhhQCyGMeTp0a/fvaw==" + }, "colormin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", @@ -2790,8 +2830,7 @@ "colors": { "version": "1.1.2", "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" }, "combined-stream": { "version": "1.0.7", @@ -2866,14 +2905,12 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -3461,8 +3498,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "4.0.0", @@ -3710,6 +3746,11 @@ "array-find-index": "^1.0.1" } }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", @@ -3780,7 +3821,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -4164,6 +4204,11 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -4510,6 +4555,23 @@ "is-regex": "^1.0.4" } }, + "es-check": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es-check/-/es-check-5.0.0.tgz", + "integrity": "sha512-30n+EZt5KjazXEvyYr2DXJCOJJWfdT1unRp5+Szlcja6uGAB3Sh3QPjRsxd2xgN9SFj4S5P8pdBISwGcDdS45Q==", + "requires": { + "acorn": "6.0.4", + "caporal": "1.1.0", + "glob": "^7.1.2" + }, + "dependencies": { + "acorn": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==" + } + } + }, "es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", @@ -4530,8 +4592,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.11.0", @@ -4935,8 +4996,7 @@ "exit-hook": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" }, "expand-brackets": { "version": "0.1.5", @@ -5028,8 +5088,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -5078,6 +5137,11 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -5423,8 +5487,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fastparse": { "version": "1.1.2", @@ -5788,8 +5851,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.4", @@ -6284,6 +6346,18 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "requires": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -6588,7 +6662,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6800,7 +6873,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6838,6 +6910,11 @@ "has-symbol-support-x": "^1.4.1" } }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -7488,7 +7565,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7497,8 +7573,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -7743,8 +7818,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-generator-fn": { "version": "1.0.0", @@ -7869,8 +7943,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-redirect": { "version": "1.0.0", @@ -7980,8 +8053,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isbinaryfile": { "version": "3.0.3", @@ -8010,8 +8082,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-api": { "version": "1.3.7", @@ -9211,8 +9282,7 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, "lodash._reinterpolate": { "version": "3.0.0", @@ -9223,8 +9293,7 @@ "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.debounce": { "version": "4.0.8", @@ -9232,11 +9301,15 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, "lodash.kebabcase": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" }, "lodash.memoize": { "version": "4.1.2", @@ -9247,8 +9320,7 @@ "lodash.merge": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", - "dev": true + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" }, "lodash.mergewith": { "version": "4.6.1", @@ -9262,6 +9334,21 @@ "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", "dev": true }, + "lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=" + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" + }, + "lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", @@ -9314,8 +9401,7 @@ "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, "lodash.upperfirst": { "version": "4.3.1", @@ -9661,6 +9747,14 @@ "regex-cache": "^0.4.2" } }, + "micromist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromist/-/micromist-1.1.0.tgz", + "integrity": "sha512-+CQ76pabE9egniSEdmDuH+j2cYyIBKP97kujG8ZLZyLCRq5ExwtIy4DPHPFrq4jVbhMRBnyjuH50KU9Ohs8QCg==", + "requires": { + "lodash.camelcase": "^4.3.0" + } + }, "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", @@ -9720,7 +9814,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -9728,8 +9821,7 @@ "minimist": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minimist-options": { "version": "3.0.2", @@ -9784,7 +9876,6 @@ "version": "0.5.1", "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -9792,8 +9883,7 @@ "minimist": { "version": "0.0.8", "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -9852,8 +9942,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "multicast-dns": { "version": "6.2.3", @@ -10130,6 +10219,16 @@ "which": "^1.2.10" } }, + "npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "requires": { + "ansi": "~0.3.1", + "are-we-there-yet": "~1.1.2", + "gauge": "~1.2.5" + } + }, "null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", @@ -10145,8 +10244,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nwsapi": { "version": "2.0.9", @@ -10163,8 +10261,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", @@ -10273,7 +10370,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -10435,14 +10531,12 @@ "os-shim": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", - "dev": true + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=" }, "os-tmpdir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "output-file-sync": { "version": "1.1.2", @@ -10684,8 +10778,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -10748,14 +10841,12 @@ "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "^2.0.0" } @@ -11400,6 +11491,15 @@ } } }, + "prettyjson": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", + "integrity": "sha1-/P+rQdGcq0365eV15kJGYZsS0ok=", + "requires": { + "colors": "^1.1.2", + "minimist": "^1.2.0" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -11415,8 +11515,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "progress": { "version": "2.0.3", @@ -11685,7 +11784,6 @@ "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12427,7 +12525,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, "requires": { "is-promise": "^2.1.0" } @@ -12441,6 +12538,11 @@ "aproba": "^1.1.1" } }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" + }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", @@ -12476,8 +12578,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -13257,7 +13358,6 @@ "version": "1.0.15", "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", - "dev": true, "requires": { "concat-stream": "^1.4.7", "os-shim": "^0.1.2" @@ -13389,6 +13489,11 @@ "figgy-pudding": "^3.5.1" } }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", @@ -13698,7 +13803,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -13707,14 +13811,12 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -13725,7 +13827,6 @@ "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -13745,7 +13846,6 @@ "version": "3.0.1", "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -13895,6 +13995,143 @@ } } }, + "tabtab": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tabtab/-/tabtab-2.2.2.tgz", + "integrity": "sha1-egR/FDsBC0y9MfhX6ClhUSy/ThQ=", + "requires": { + "debug": "^2.2.0", + "inquirer": "^1.0.2", + "lodash.difference": "^4.5.0", + "lodash.uniq": "^4.5.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "npmlog": "^2.0.3", + "object-assign": "^4.1.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "external-editor": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", + "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", + "requires": { + "extend": "^3.0.0", + "spawn-sync": "^1.0.15", + "tmp": "^0.0.29" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "inquirer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz", + "integrity": "sha1-TexvMvN+97sLLtPx0aXD9UUHSRg=", + "requires": { + "ansi-escapes": "^1.1.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "external-editor": "^1.1.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "mute-stream": "0.0.6", + "pinkie-promise": "^2.0.0", + "run-async": "^2.2.0", + "rx": "^4.1.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "mute-stream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz", + "integrity": "sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s=" + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "requires": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "requires": { + "os-tmpdir": "~1.0.1" + } + } + } + }, "tapable": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", @@ -14103,8 +14340,7 @@ "through": { "version": "2.3.8", "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.5", @@ -14292,8 +14528,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uglify-js": { "version": "3.4.9", @@ -14579,8 +14814,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util.promisify": { "version": "1.0.0", @@ -16514,6 +16748,31 @@ "string-width": "^2.1.1" } }, + "winston": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz", + "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==", + "requires": { + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "dependencies": { + "async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + } + } + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -16564,8 +16823,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", diff --git a/package.json b/package.json index ceecab67..fcfcbd17 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,10 @@ "webpack": "^4.4.0" }, "dependencies": { - "schema-utils": "^1.0.0", - "normalize-url": "^3.0.0", + "es-check": "^5.0.0", "loader-utils": "^1.1.0", + "normalize-url": "^3.0.0", + "schema-utils": "^1.0.0", "webpack-sources": "^1.1.0" }, "devDependencies": { diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 934742bc..0a040761 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -5,6 +5,7 @@ /* eslint prefer-arrow-func: 0 */ /* eslint prefer-rest-params: 0 */ /* eslint prefer-arrow-callback: 0 */ +/* eslint prefer-template: 0 */ var normalizeUrl = require('normalize-url'); @@ -64,9 +65,9 @@ function getCurrentScriptUrl(moduleId) { return [src.replace('.js', '.css')]; } return fileMap.split(',').map(function(mapRule) { - var reg = new RegExp(`${filename}\\.js$`, 'g'); + var reg = new RegExp(filename + '\\.js$', 'g'); return normalizeUrl( - src.replace(reg, `${mapRule.replace(/{fileName}/g, filename)}.css`), + src.replace(reg, mapRule.replace(/{fileName}/g, filename) + '.css'), { stripWWW: false } ); }); @@ -99,7 +100,7 @@ function updateCss(el, url) { el.parentNode.removeChild(el); }); - newEl.href = `${url}?${Date.now()}`; + newEl.href = url + '?' + Date.now(); el.parentNode.appendChild(newEl); } diff --git a/test/TestCases.test.js b/test/TestCases.test.js index 10a49bf0..c8723648 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -1,5 +1,6 @@ import fs from 'fs'; import path from 'path'; +import { exec } from 'child_process'; import webpack from 'webpack'; @@ -92,3 +93,24 @@ describe('TestCases', () => { } } }); + +describe('HMR', () => { + it('matches snapshot', () => { + const hmr = fs + .readFileSync(path.join(__dirname, '../src/hmr/hotModuleReplacement.js')) + .toString(); + + expect(hmr).toMatchSnapshot(); + }); + + it('is es5 only', () => { + exec( + './node_modules/.bin/es-check es5 src/hmr/hotModuleReplacement.js', + (error, stdout, stderr) => { + expect( + stderr.indexOf('there were no ES version matching errors!') > -1 + ).toBe(true); + } + ); + }); +}); diff --git a/test/__snapshots__/TestCases.test.js.snap b/test/__snapshots__/TestCases.test.js.snap new file mode 100644 index 00000000..8b2343e1 --- /dev/null +++ b/test/__snapshots__/TestCases.test.js.snap @@ -0,0 +1,170 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`HMR matches snapshot 1`] = ` +"/* global document, window */ +/* eslint func-names: 0 */ +/* eslint no-var: 0 */ +/* eslint vars-on-top: 0 */ +/* eslint prefer-arrow-func: 0 */ +/* eslint prefer-rest-params: 0 */ +/* eslint prefer-arrow-callback: 0 */ +/* eslint prefer-template: 0 */ + +var normalizeUrl = require('normalize-url'); + +var srcByModuleId = Object.create(null); + +var noDocument = typeof document === 'undefined'; + +var forEach = Array.prototype.forEach; + +function debounce(fn, time) { + var timeout = 0; + + // eslint-disable-next-line func-names + return function() { + var self = this; + var args = arguments; + + // eslint-disable-next-line prefer-rest-params + var functionCall = function functionCall() { + return fn.apply(self, args); + }; + + clearTimeout(timeout); + timeout = setTimeout(functionCall, time); + }; +} + +function noop() {} + +function getCurrentScriptUrl(moduleId) { + var src = srcByModuleId[moduleId]; + + if (!src) { + if (document.currentScript) { + src = document.currentScript.src; + } else { + var scripts = document.getElementsByTagName('script'); + var lastScriptTag = scripts[scripts.length - 1]; + + if (lastScriptTag) { + src = lastScriptTag.src; + } + } + srcByModuleId[moduleId] = src; + } + + return function(fileMap) { + if (!src) { + return null; + } + var splitResult = src.split(/([^\\\\\\\\/]+)\\\\.js$/); + var filename = splitResult && splitResult[1]; + if (!filename) { + return [src.replace('.js', '.css')]; + } + if (!fileMap) { + return [src.replace('.js', '.css')]; + } + return fileMap.split(',').map(function(mapRule) { + var reg = new RegExp(filename + '\\\\\\\\.js$', 'g'); + return normalizeUrl( + src.replace(reg, mapRule.replace(/{fileName}/g, filename) + '.css'), + { stripWWW: false } + ); + }); + }; +} + +function updateCss(el, url) { + if (!url) { + url = el.href.split('?')[0]; + } + if (el.isLoaded === false) { + // We seem to be about to replace a css link that hasn't loaded yet. + // We're probably changing the same file more than once. + return; + } + if (!url || !(url.indexOf('.css') > -1)) return; + + el.visited = true; + var newEl = el.cloneNode(); // eslint-disable-line vars-on-top + + newEl.isLoaded = false; + + newEl.addEventListener('load', function() { + newEl.isLoaded = true; + el.parentNode.removeChild(el); + }); + + newEl.addEventListener('error', function() { + newEl.isLoaded = true; + el.parentNode.removeChild(el); + }); + + newEl.href = url + '?' + Date.now(); + el.parentNode.appendChild(newEl); +} + +function getReloadUrl(href, src) { + var ret; + href = normalizeUrl(href, { stripWWW: false }); + // eslint-disable-next-line array-callback-return + src.some(function(url) { + if (href.indexOf(src) > -1) { + ret = url; + } + }); + return ret; +} + +function reloadStyle(src) { + var elements = document.querySelectorAll('link'); + var loaded = false; + + forEach.call(elements, function(el) { + var url = getReloadUrl(el.href, src); + + if (el.visited === true) return; + + if (url) { + updateCss(el, url); + loaded = true; + } + }); + + return loaded; +} + +function reloadAll() { + var elements = document.querySelectorAll('link'); + forEach.call(elements, function(el) { + if (el.visited === true) return; + updateCss(el); + }); +} + +module.exports = function(moduleId, options) { + if (noDocument) { + return noop; + } + + // eslint-disable-next-line vars-on-top + var getScriptSrc = getCurrentScriptUrl(moduleId); + + function update() { + var src = getScriptSrc(options.filename); + var reloaded = reloadStyle(src); + if (reloaded && !options.reloadAll) { + console.log('[HMR] css reload %s', src.join(' ')); + } else { + console.log('[HMR] Reload all css'); + reloadAll(); + } + } + + return debounce(update, 10); +}; +" +`; diff --git a/test/cases/hmr/expected/main.js b/test/cases/hmr/expected/main.js new file mode 100644 index 00000000..d3cb7130 --- /dev/null +++ b/test/cases/hmr/expected/main.js @@ -0,0 +1,94 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +// extracted by mini-css-extract-plugin + +/***/ }) +/******/ ]); \ No newline at end of file From 0c93cf08926c03471ef5db02882f6e1b81a6bdf5 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 30 Jan 2019 00:48:49 -0800 Subject: [PATCH 17/30] fix: moved es checker to dev dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fcfcbd17..4d45c96d 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "webpack": "^4.4.0" }, "dependencies": { - "es-check": "^5.0.0", "loader-utils": "^1.1.0", "normalize-url": "^3.0.0", "schema-utils": "^1.0.0", @@ -63,6 +62,7 @@ "css-loader": "^0.28.10", "del": "^3.0.0", "del-cli": "^1.1.0", + "es-check": "^5.0.0", "eslint": "^4.17.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-prettier": "^2.6.0", @@ -74,7 +74,7 @@ "pre-commit": "^1.2.2", "prettier": "^1.11.1", "standard-version": "^4.3.0", - "webpack": "^4.14.0", + "webpack": "^4.28.0", "webpack-cli": "^2.0.13", "webpack-defaults": "^2.3.0", "webpack-dev-server": "^3.1.14" From c111e9bb683e31ff515941890b5439c2de99c129 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Sat, 2 Mar 2019 18:35:01 -0800 Subject: [PATCH 18/30] docs: updated readme to detail hmr adding examples and some details around the new loader options which enable hot module reloading. Including information and configuration examples for css-modules and standard css file reloading --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 72c21d77..f8759ec9 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,6 @@ Compared to the extract-text-webpack-plugin: * Easier to use * Specific to CSS -TODO: - -* HMR support

Install

@@ -69,8 +66,9 @@ module.exports = { loader: MiniCssExtractPlugin.loader, options: { // you can specify a publicPath here - // by default it use publicPath in webpackOptions.output - publicPath: '../' + // by default it uses publicPath in webpackOptions.output + publicPath: '../', + hot: process.env.NODE_ENV === 'development' } }, "css-loader" @@ -149,7 +147,12 @@ module.exports = { { test: /\.(sa|sc|c)ss$/, use: [ - devMode ? 'style-loader' : MiniCssExtractPlugin.loader, + { + loader: MiniCssExtractPlugin.loader, + options: { + hot: process.env.NODE_ENV === 'development' + } + }, 'css-loader', 'postcss-loader', 'sass-loader', @@ -160,6 +163,52 @@ module.exports = { } ``` +#### Hot Module Reloading (HMR) + +extract-mini-css-plugin supports hot reloading of actual css files in development. Some options are provided to enable HMR of both standard stylesheets and locally scoped css or CSS modules. Below is an example configuration of mini-css for HMR use with CSS modules + +**webpack.config.js** + +```js +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +module.exports = { + plugins: [ + new MiniCssExtractPlugin({ + // Options similar to the same options in webpackOptions.output + // both options are optional + filename: "[name].css", + chunkFilename: "[id].css" + }) + ], + module: { + rules: [ + { + test: /\.css$/, + use: [ + { + loader: MiniCssExtractPlugin.loader, + options: { + // only enable hot in development + hot: process.env.NODE_ENV === 'development', + // modules enables hmr of css modules which + // need to be handled differently compared to typical css files + modules: true, + // in the event that HMR is not working correctly for your setup. + // a fallback option has been implemented to force css files to be reloaded + // reloadAll will force all stylesheets to be reloaded when receiving an HMR update + // this option is helpful when dealing with css-modules as they are harder to HMR + reloadAll: true, + } + }, + "css-loader" + ] + } + ] + } +} +``` + + ### Minimizing For Production While webpack 5 is likely to come with a CSS minimizer built-in, with webpack 4 you need to bring your own. To minify the output, use a plugin like [optimize-css-assets-webpack-plugin](https://github.com/NMFR/optimize-css-assets-webpack-plugin). Setting `optimization.minimizer` overrides the defaults provided by webpack, so make sure to also specify a JS minimizer: From 936b8d328968a7011c71b3bf72c3f49270197ab7 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Fri, 15 Mar 2019 12:16:46 -0700 Subject: [PATCH 19/30] fix: lock webpack version to avoid npm acorn issue --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4d45c96d..b76e37ab 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "pre-commit": "^1.2.2", "prettier": "^1.11.1", "standard-version": "^4.3.0", - "webpack": "^4.28.0", + "webpack": "4.28.0", "webpack-cli": "^2.0.13", "webpack-defaults": "^2.3.0", "webpack-dev-server": "^3.1.14" From b08a3ce036c4960cc423e8388990d7f638272fee Mon Sep 17 00:00:00 2001 From: zackjackson Date: Tue, 26 Mar 2019 17:34:27 -0700 Subject: [PATCH 20/30] fix: renaming hot to hmr adding console log when noDocument available updating readme with new api --- README.md | 9 +++------ src/hmr/hotModuleReplacement.js | 1 + test/cases/hmr/webpack.config.js | 1 - test/cases/js-hash/webpack.config.js | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f8759ec9..8d52d4d3 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ module.exports = { // you can specify a publicPath here // by default it uses publicPath in webpackOptions.output publicPath: '../', - hot: process.env.NODE_ENV === 'development' + hmr: process.env.NODE_ENV === 'development' } }, "css-loader" @@ -150,7 +150,7 @@ module.exports = { { loader: MiniCssExtractPlugin.loader, options: { - hot: process.env.NODE_ENV === 'development' + hmr: process.env.NODE_ENV === 'development' } }, 'css-loader', @@ -189,10 +189,7 @@ module.exports = { loader: MiniCssExtractPlugin.loader, options: { // only enable hot in development - hot: process.env.NODE_ENV === 'development', - // modules enables hmr of css modules which - // need to be handled differently compared to typical css files - modules: true, + hmr: process.env.NODE_ENV === 'development', // in the event that HMR is not working correctly for your setup. // a fallback option has been implemented to force css files to be reloaded // reloadAll will force all stylesheets to be reloaded when receiving an HMR update diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 0a040761..de2e8666 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -144,6 +144,7 @@ function reloadAll() { module.exports = function(moduleId, options) { if (noDocument) { + console.log('no window.document found, will not HMR CSS'); return noop; } diff --git a/test/cases/hmr/webpack.config.js b/test/cases/hmr/webpack.config.js index aa6fcb8d..e3493add 100644 --- a/test/cases/hmr/webpack.config.js +++ b/test/cases/hmr/webpack.config.js @@ -11,7 +11,6 @@ module.exports = { loader: Self.loader, options: { hmr: true, - modules: true, reloadAll: true }, }, diff --git a/test/cases/js-hash/webpack.config.js b/test/cases/js-hash/webpack.config.js index e9865055..e9219928 100644 --- a/test/cases/js-hash/webpack.config.js +++ b/test/cases/js-hash/webpack.config.js @@ -10,7 +10,7 @@ module.exports = [1, 2].map(n => ({ { loader: Self.loader, options:{ - hot: false + hmr: false } }, { From 9f16d9945b50abc45ebcdab863dd0153fb23e876 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Tue, 26 Mar 2019 17:37:05 -0700 Subject: [PATCH 21/30] fix: remove unused method and using locals for css modules --- src/index.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/index.js b/src/index.js index 6e9db066..fb9a3e22 100644 --- a/src/index.js +++ b/src/index.js @@ -395,21 +395,6 @@ class MiniCssExtractPlugin { }); } - traverseDepthFirst(root, visit) { - let nodesToVisit = [root]; - - while (nodesToVisit.length > 0) { - const currentNode = nodesToVisit.shift(); - - if (currentNode !== null && typeof currentNode === 'object') { - const children = Object.values(currentNode); - nodesToVisit = [...children, ...nodesToVisit]; - } - - visit(currentNode); - } - } - getCssChunkObject(mainChunk) { const obj = {}; for (const chunk of mainChunk.getAllAsyncChunks()) { From 79001b81356af125f7d0011091b31a90c85f5316 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Tue, 26 Mar 2019 20:48:41 -0700 Subject: [PATCH 22/30] test: updating tests and snapshots --- package.json | 1 + test/TestCases.test.js | 15 +++++++-------- test/__snapshots__/TestCases.test.js.snap | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index b76e37ab..8121e2aa 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "eslint": "^4.17.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-prettier": "^2.6.0", + "execa": "^1.0.0", "file-loader": "^1.1.11", "husky": "^0.14.3", "jest": "^22.2.2", diff --git a/test/TestCases.test.js b/test/TestCases.test.js index c8723648..c0cb3a39 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -1,8 +1,8 @@ import fs from 'fs'; import path from 'path'; -import { exec } from 'child_process'; import webpack from 'webpack'; +import execa from 'execa'; describe('TestCases', () => { const casesDirectory = path.resolve(__dirname, 'cases'); @@ -104,13 +104,12 @@ describe('HMR', () => { }); it('is es5 only', () => { - exec( - './node_modules/.bin/es-check es5 src/hmr/hotModuleReplacement.js', - (error, stdout, stderr) => { - expect( - stderr.indexOf('there were no ES version matching errors!') > -1 - ).toBe(true); - } + const { stderr } = execa.shellSync( + 'npx es-check es5 src/hmr/hotModuleReplacement.js' ); + + expect( + stderr.indexOf('there were no ES version matching errors') > -1 + ).toBe(true); }); }); diff --git a/test/__snapshots__/TestCases.test.js.snap b/test/__snapshots__/TestCases.test.js.snap index 8b2343e1..f0f20449 100644 --- a/test/__snapshots__/TestCases.test.js.snap +++ b/test/__snapshots__/TestCases.test.js.snap @@ -147,6 +147,7 @@ function reloadAll() { module.exports = function(moduleId, options) { if (noDocument) { + console.log('no window.document found, will not HMR CSS'); return noop; } From 59797ccfa17319dfd97282378802532087d58271 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Tue, 26 Mar 2019 21:10:54 -0700 Subject: [PATCH 23/30] fix: using older version of normalize for older node support --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8121e2aa..508f91a5 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "dependencies": { "loader-utils": "^1.1.0", - "normalize-url": "^3.0.0", + "normalize-url": "^2.0.1", "schema-utils": "^1.0.0", "webpack-sources": "^1.1.0" }, From c149cc229d384faca3495ee66ae175d851ec2509 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Tue, 26 Mar 2019 21:21:53 -0700 Subject: [PATCH 24/30] fix: removing reloadAll option --- README.md | 5 ----- src/hmr/hotModuleReplacement.js | 2 +- test/__snapshots__/TestCases.test.js.snap | 2 +- test/cases/hmr/webpack.config.js | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 8d52d4d3..9c278433 100644 --- a/README.md +++ b/README.md @@ -190,11 +190,6 @@ module.exports = { options: { // only enable hot in development hmr: process.env.NODE_ENV === 'development', - // in the event that HMR is not working correctly for your setup. - // a fallback option has been implemented to force css files to be reloaded - // reloadAll will force all stylesheets to be reloaded when receiving an HMR update - // this option is helpful when dealing with css-modules as they are harder to HMR - reloadAll: true, } }, "css-loader" diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index de2e8666..20a4978b 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -154,7 +154,7 @@ module.exports = function(moduleId, options) { function update() { var src = getScriptSrc(options.filename); var reloaded = reloadStyle(src); - if (reloaded && !options.reloadAll) { + if (reloaded) { console.log('[HMR] css reload %s', src.join(' ')); } else { console.log('[HMR] Reload all css'); diff --git a/test/__snapshots__/TestCases.test.js.snap b/test/__snapshots__/TestCases.test.js.snap index f0f20449..0d83a162 100644 --- a/test/__snapshots__/TestCases.test.js.snap +++ b/test/__snapshots__/TestCases.test.js.snap @@ -157,7 +157,7 @@ module.exports = function(moduleId, options) { function update() { var src = getScriptSrc(options.filename); var reloaded = reloadStyle(src); - if (reloaded && !options.reloadAll) { + if (reloaded) { console.log('[HMR] css reload %s', src.join(' ')); } else { console.log('[HMR] Reload all css'); diff --git a/test/cases/hmr/webpack.config.js b/test/cases/hmr/webpack.config.js index e3493add..078b7182 100644 --- a/test/cases/hmr/webpack.config.js +++ b/test/cases/hmr/webpack.config.js @@ -11,7 +11,6 @@ module.exports = { loader: Self.loader, options: { hmr: true, - reloadAll: true }, }, 'css-loader', From 33109c422f3c1d59310397d97d1bffac5c8975af Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 3 Apr 2019 21:58:19 -0700 Subject: [PATCH 25/30] fix: auto detect locals and reloadAll --- README.md | 9 ++++++++- src/hmr/hotModuleReplacement.js | 11 +++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9c278433..82503b5c 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,12 @@ module.exports = { #### Hot Module Reloading (HMR) -extract-mini-css-plugin supports hot reloading of actual css files in development. Some options are provided to enable HMR of both standard stylesheets and locally scoped css or CSS modules. Below is an example configuration of mini-css for HMR use with CSS modules +extract-mini-css-plugin supports hot reloading of actual css files in development. Some options are provided to enable HMR of both standard stylesheets and locally scoped CSS or CSS modules. Below is an example configuration of mini-css for HMR use with CSS modules. + + +While we attempt to hmr css-modules. It is not easy to perform when code-splitting with custom chunk names. `reloadAll` is an option that should only be enabled if HMR isn't working correctly. The core challenge with css-modules is that when code-split, the chunk ids can and do end up different compared to the filename. + + **webpack.config.js** @@ -190,6 +195,8 @@ module.exports = { options: { // only enable hot in development hmr: process.env.NODE_ENV === 'development', + // if hmr does not work, this is a forceful method. + reloadAll: true } }, "css-loader" diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 20a4978b..3eaa96c3 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -154,7 +154,14 @@ module.exports = function(moduleId, options) { function update() { var src = getScriptSrc(options.filename); var reloaded = reloadStyle(src); - if (reloaded) { + + if (options.locals) { + console.log('[HMR] Detected local css modules. Reload all css'); + reloadAll(); + return; + } + + if (reloaded || !options.reloadAll) { console.log('[HMR] css reload %s', src.join(' ')); } else { console.log('[HMR] Reload all css'); @@ -162,5 +169,5 @@ module.exports = function(moduleId, options) { } } - return debounce(update, 10); + return debounce(update, 50); }; From 6981838f0225561a87c926b411ee2062c4a7036d Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 3 Apr 2019 22:03:16 -0700 Subject: [PATCH 26/30] feat: adding order warning option disables order warnings being logged to terminal --- README.md | 4 +++- src/index.js | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 82503b5c..035b3f7a 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,9 @@ module.exports = { plugins: [ new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css" + chunkFilename: "[id].css", + // disables order warnings being logged in terminal after build + orderWarning: false }) ], module: { diff --git a/src/index.js b/src/index.js index fb9a3e22..a8abba60 100644 --- a/src/index.js +++ b/src/index.js @@ -481,16 +481,20 @@ class MiniCssExtractPlugin { // use list with fewest failed deps // and emit a warning const fallbackModule = bestMatch.pop(); - compilation.warnings.push( - new Error( - `chunk ${chunk.name || chunk.id} [mini-css-extract-plugin]\n` + - 'Conflicting order between:\n' + - ` * ${fallbackModule.readableIdentifier(requestShortener)}\n` + - `${bestMatchDeps - .map((m) => ` * ${m.readableIdentifier(requestShortener)}`) - .join('\n')}` - ) - ); + if (this.options.orderWarning) { + compilation.warnings.push( + new Error( + `chunk ${chunk.name || chunk.id} [${pluginName}]\n` + + 'Conflicting order between:\n' + + ` * ${fallbackModule.readableIdentifier( + requestShortener + )}\n` + + `${bestMatchDeps + .map((m) => ` * ${m.readableIdentifier(requestShortener)}`) + .join('\n')}` + ) + ); + } usedModules.add(fallbackModule); } } From 2708a67a100921d452812dbc97ddb48eebeb1c0a Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 3 Apr 2019 22:14:43 -0700 Subject: [PATCH 27/30] fix: added default option for orderWarning --- src/hmr/hotModuleReplacement.js | 2 +- src/index.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hmr/hotModuleReplacement.js b/src/hmr/hotModuleReplacement.js index 3eaa96c3..62f08f79 100644 --- a/src/hmr/hotModuleReplacement.js +++ b/src/hmr/hotModuleReplacement.js @@ -161,7 +161,7 @@ module.exports = function(moduleId, options) { return; } - if (reloaded || !options.reloadAll) { + if (reloaded && !options.reloadAll) { console.log('[HMR] css reload %s', src.join(' ')); } else { console.log('[HMR] Reload all css'); diff --git a/src/index.js b/src/index.js index a8abba60..8c6aa7fc 100644 --- a/src/index.js +++ b/src/index.js @@ -113,6 +113,7 @@ class MiniCssExtractPlugin { this.options = Object.assign( { filename: '[name].css', + orderWarning: true, }, options ); From 4d1c75dd2f9d835d0292f52c45a4b9df19392a62 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 3 Apr 2019 22:21:02 -0700 Subject: [PATCH 28/30] test: updating test expectations --- test/__snapshots__/TestCases.test.js.snap | 11 +++++++++-- test/cases/hmr/expected/main.js | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/test/__snapshots__/TestCases.test.js.snap b/test/__snapshots__/TestCases.test.js.snap index 0d83a162..b6f3c48b 100644 --- a/test/__snapshots__/TestCases.test.js.snap +++ b/test/__snapshots__/TestCases.test.js.snap @@ -157,7 +157,14 @@ module.exports = function(moduleId, options) { function update() { var src = getScriptSrc(options.filename); var reloaded = reloadStyle(src); - if (reloaded) { + + if (options.locals) { + console.log('[HMR] Detected local css modules. Reload all css'); + reloadAll(); + return; + } + + if (reloaded && !options.reloadAll) { console.log('[HMR] css reload %s', src.join(' ')); } else { console.log('[HMR] Reload all css'); @@ -165,7 +172,7 @@ module.exports = function(moduleId, options) { } } - return debounce(update, 10); + return debounce(update, 50); }; " `; diff --git a/test/cases/hmr/expected/main.js b/test/cases/hmr/expected/main.js index d3cb7130..0b125150 100644 --- a/test/cases/hmr/expected/main.js +++ b/test/cases/hmr/expected/main.js @@ -89,6 +89,8 @@ /***/ (function(module, exports, __webpack_require__) { // extracted by mini-css-extract-plugin + if(false) { var cssReload; } + /***/ }) /******/ ]); \ No newline at end of file From 15dd658d2b36c42785f49f9e0eaca3092d5c39e6 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Wed, 3 Apr 2019 22:24:01 -0700 Subject: [PATCH 29/30] docs: updating readme about order warning flags --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 035b3f7a..c509405d 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ module.exports = { filename: "[name].css", chunkFilename: "[id].css", // disables order warnings being logged in terminal after build - orderWarning: false + orderWarning: true, // Disable to remove warnings about conflicting order between imports }) ], module: { From 7f4159ee12a3277c96028e9fcaceaac7a3091576 Mon Sep 17 00:00:00 2001 From: zackjackson Date: Thu, 4 Apr 2019 12:16:06 -0700 Subject: [PATCH 30/30] docs: updating docs about filtering warnings warningsFilter --- README.md | 8 +++++--- src/index.js | 25 ++++++++++--------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index c509405d..a2022c2a 100644 --- a/README.md +++ b/README.md @@ -228,9 +228,7 @@ module.exports = { plugins: [ new MiniCssExtractPlugin({ filename: "[name].css", - chunkFilename: "[id].css", - // disables order warnings being logged in terminal after build - orderWarning: true, // Disable to remove warnings about conflicting order between imports + chunkFilename: "[id].css" }) ], module: { @@ -364,6 +362,10 @@ module.exports = { For long term caching use `filename: "[contenthash].css"`. Optionally add `[name]`. +### Remove Order Warnings + +If the terminal is getting bloated with chunk order warnings. You can filter by configuring [warningsFilter](https://webpack.js.org/configuration/stats/) withing the webpack stats option + ### Media Query Plugin If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins: diff --git a/src/index.js b/src/index.js index 8c6aa7fc..93760d87 100644 --- a/src/index.js +++ b/src/index.js @@ -113,7 +113,6 @@ class MiniCssExtractPlugin { this.options = Object.assign( { filename: '[name].css', - orderWarning: true, }, options ); @@ -482,20 +481,16 @@ class MiniCssExtractPlugin { // use list with fewest failed deps // and emit a warning const fallbackModule = bestMatch.pop(); - if (this.options.orderWarning) { - compilation.warnings.push( - new Error( - `chunk ${chunk.name || chunk.id} [${pluginName}]\n` + - 'Conflicting order between:\n' + - ` * ${fallbackModule.readableIdentifier( - requestShortener - )}\n` + - `${bestMatchDeps - .map((m) => ` * ${m.readableIdentifier(requestShortener)}`) - .join('\n')}` - ) - ); - } + compilation.warnings.push( + new Error( + `chunk ${chunk.name || chunk.id} [${pluginName}]\n` + + 'Conflicting order between:\n' + + ` * ${fallbackModule.readableIdentifier(requestShortener)}\n` + + `${bestMatchDeps + .map((m) => ` * ${m.readableIdentifier(requestShortener)}`) + .join('\n')}` + ) + ); usedModules.add(fallbackModule); } }