From c832aadd07ba4f8a2121c0338ffb5a112f28b6ab Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Sun, 8 Apr 2018 01:14:32 +0200 Subject: [PATCH 01/16] updated webpack to 4.5.0 - fixes #110 --- example/package.json | 2 +- library/lib/build.js | 22 +- library/lib/javascript.js | 9 +- library/package.json | 23 +- library/webpack-loaders/css-loader.js | 4 +- .../react-universal-client-loader.js | 2 +- .../react-universal-server-loader.js | 2 +- .../webpack-loaders/to-json-file-loader.js | 2 +- .../webpack-plugins/chunk-manifest-plugin.js | 22 +- .../webpack-plugins/config-loader-plugin.js | 6 +- .../copy-unused-files-plugin.js | 6 +- .../hot-css-replacement-plugin.js | 12 +- .../hot-module-replacement-plugin.js | 8 +- .../make-additional-entries-plugin.js | 23 +- library/webpack-plugins/merge-css-plugin.js | 42 +- .../webpack-plugins/react-universal-plugin.js | 112 ++- .../webpack-plugins/shared-modules-plugin.js | 374 --------- library/webpack-plugins/source-map-plugin.js | 8 +- .../target-based-plugins-plugin.js | 6 +- library/webpack-plugins/template-plugin.js | 10 +- .../webpack-plugins/watch-context-plugin.js | 6 +- .../websocket-communication-plugin.js | 36 +- .../absolute-path-resolver-plugin.js | 6 +- .../fragment-resolver-plugin.js | 6 +- package.json | 5 +- yarn.lock | 759 ++++++++++-------- 26 files changed, 687 insertions(+), 826 deletions(-) delete mode 100644 library/webpack-plugins/shared-modules-plugin.js diff --git a/example/package.json b/example/package.json index 523267da..1738bc1c 100644 --- a/example/package.json +++ b/example/package.json @@ -17,7 +17,7 @@ "firebase": "^4.6.2", "firebase-admin": "^5.5.1", "mjml": "^4.0.3", - "normalize.css": "^7.0.0", + "normalize.css": "^8.0.0", "react": "^16.2.0", "react-dom": "^16.2.0", "xml": "^1.0.1" diff --git a/library/lib/build.js b/library/lib/build.js index ca3e2223..369e1d67 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -1,3 +1,9 @@ +// Better logging for deprecation and other errors +process.traceDeprecation = true +process.on('unhandledRejection', (reason, p) => { + console.log('Unhandled rejection of:\n', p, '\nReason:\n', reason) +}) + const fs = require('fs-extra') const nodeExternals = require('webpack-node-externals') const path = require('path') @@ -12,7 +18,6 @@ const hotModuleReplacementPlugin = require('../webpack-plugins/hot-module-replac const makeAdditionalEntriesPlugin = require('../webpack-plugins/make-additional-entries-plugin') const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin') const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin') -const sharedModulesPlugin = require('../webpack-plugins/shared-modules-plugin') const sourceMapPlugin = require('../webpack-plugins/source-map-plugin') const targetBasedPluginsPlugin = require('../webpack-plugins/target-based-plugins-plugin') const templatePlugin = require('../webpack-plugins/template-plugin') @@ -26,6 +31,7 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const ExtendedAPIPlugin = require('webpack/lib/ExtendedAPIPlugin') const ProgressBarPlugin = require('progress-bar-webpack-plugin') const findYarnWorkspaceRoot = require('find-yarn-workspace-root') +const TimeFixPlugin = require('time-fix-plugin') // https://github.com/webpack/watchpack/issues/25 const isProduction = process.env.NODE_ENV === 'production' @@ -103,7 +109,9 @@ module.exports = function build({ watch }) { // because webpack stores state in the options object :-( function getOptions() { return { + mode: isProduction ? 'production' : 'development', target: 'node', + devtool: false, output: { filename: '[name]', chunkFilename: '[name]-[hash].js', @@ -127,11 +135,17 @@ module.exports = function build({ watch }) { ].filter(Boolean) }, context: srcDir, + optimization: { + namedChunks: false, + minimize: false, + splitChunks: false + }, module: { // noParse: https://webpack.js.org/configuration/module/#module-noparse rules: [{ oneOf: [ { + type: 'json', test: /\.json$/, loaders: [] }, @@ -224,6 +238,7 @@ module.exports = function build({ watch }) { sourceMapPlugin(), ].filter(Boolean), node: [ + new TimeFixPlugin(), watch && new ExtendedAPIPlugin(), configLoaderPlugin(), watchContextPlugin(), @@ -234,9 +249,7 @@ module.exports = function build({ watch }) { watch && hotCssReplacementPlugin() ].filter(Boolean), web: [ - sharedModulesPlugin(), chunkManifestPlugin(), - isProduction && new webpack.optimize.UglifyJsPlugin({ sourceMap: true }), watch && hotModuleReplacementPlugin() ].filter(Boolean) }) @@ -304,11 +317,12 @@ module.exports = function build({ watch }) { const [oldKeys, newKeys] = [Object.keys(entries), Object.keys(newEntries)] const entriesChanged = !oldKeys.every(x => newKeys.includes(x)) || !newKeys.every(x => oldKeys.includes(x)) + console.log('\nWaiting for file changes...\n') + if (entriesChanged) { console.log('Entries changed, restarting watch') watching.close(() => { start(newEntries) }) } - console.log('\nWaiting for file changes...\n') } } } catch (e) { console.error(e.message) } diff --git a/library/lib/javascript.js b/library/lib/javascript.js index c42366a5..c3cbfc85 100644 --- a/library/lib/javascript.js +++ b/library/lib/javascript.js @@ -8,17 +8,16 @@ function getSharedChunkFileNames({ universalChunkNames, manifest }) { const sharedChunks = [] universalChunkNames.forEach(universalChunkName => { - addParents(manifest[universalChunkName].parents) + addDependencies(manifest[universalChunkName].dependencies) }) return sharedChunks - function addParents(parents) { - parents.map(x => manifest[x]).forEach(addFilenames) + function addDependencies(dependencies) { + dependencies.map(x => manifest[x]).forEach(addFilenames) } - function addFilenames({ filename, hasRuntime, parents }) { - addParents(parents) + function addFilenames({ filename, hasRuntime }) { if (!sharedChunks.includes(filename)) { if (hasRuntime) sharedChunks.unshift(filename) else sharedChunks.push(filename) diff --git a/library/package.json b/library/package.json index a4370447..d2970327 100644 --- a/library/package.json +++ b/library/package.json @@ -30,31 +30,31 @@ "caniuse-lite": "^1.0.30000775", "case-sensitive-paths-webpack-plugin": "^2.1.1", "compression": "^1.7.1", - "cross-spawn": "^5.1.0", + "cross-spawn": "^6.0.5", "cssnano": "^3.10.0", "eslint": "^4.12.1", - "eslint-config-standard": "^10.2.1", - "eslint-config-standard-react": "^5.0.0", + "eslint-config-standard": "^11.0.0", + "eslint-config-standard-react": "^6.0.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-jsx-a11y": "^6.0.2", - "eslint-plugin-node": "^5.2.1", + "eslint-plugin-node": "^6.0.1", "eslint-plugin-promise": "^3.6.0", "eslint-plugin-react": "^7.5.1", "eslint-plugin-standard": "^3.0.1", "express": "^4.16.2", "file-loader": "^1.1.5", "find-yarn-workspace-root": "^1.0.0", - "fs-extra": "^4.0.2", + "fs-extra": "^5.0.0", "gm": "^1.23.0", "helmet": "^3.9.0", "history": "^4.7.2", "hoist-non-react-statics": "^2.3.1", "image-maxsize-webpack-loader": "^1.0.0", - "image-webpack-loader": "^3.4.2", + "image-webpack-loader": "^4.2.0", "json-loader": "^0.5.7", "loader-utils": "^1.1.0", "postcss": "^6.0.14", - "postcss-apply": "^0.8.0", + "postcss-apply": "^0.9.0", "postcss-cssnext": "^3.0.2", "postcss-import": "^11.0.0", "postcss-modules": "^1.1.0", @@ -63,11 +63,14 @@ "react": "^16.2.0", "react-dom": "^16.2.0", "source-map": "^0.6.1", - "url-loader": "^0.6.2", + "tapable": "^1.0.0", + "time-fix-plugin": "^2.0.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "url-loader": "^1.0.1", "walk-sync": "^0.3.1", - "webpack": "^3.8.1", + "webpack": "^4.5.0", "webpack-node-externals": "^1.6.0", - "ws": "^3.3.2" + "ws": "^5.1.1" }, "keywords": [ "webpack", diff --git a/library/webpack-loaders/css-loader.js b/library/webpack-loaders/css-loader.js index c1fbf730..c80c10f3 100644 --- a/library/webpack-loaders/css-loader.js +++ b/library/webpack-loaders/css-loader.js @@ -43,7 +43,7 @@ module.exports = function CssLoader(source, map) { const { minifyOnly = false } = loaderUtils.getOptions(this) || {} const plugins = createPlugins(minifyOnly, handlers) - const filename = relative(this.options.context, this.resourcePath) + const filename = relative(this.rootContext, this.resourcePath) const options = { from: this.resourcePath, to : this.resourcePath, @@ -81,7 +81,7 @@ module.exports = function CssLoader(source, map) { function executeModuleAt(url) { return source => { - const completeSource = `const __webpack_public_path__ = '${self.options.output.publicPath || '/'}'\n` + source + const completeSource = `const __webpack_public_path__ = '${self._compiler.options.output.publicPath || '/'}'\n` + source return self.exec(completeSource, url) } } diff --git a/library/webpack-loaders/react-universal-client-loader.js b/library/webpack-loaders/react-universal-client-loader.js index 5b0874ac..03467b40 100644 --- a/library/webpack-loaders/react-universal-client-loader.js +++ b/library/webpack-loaders/react-universal-client-loader.js @@ -3,7 +3,7 @@ const { relative } = require('path') module.exports = ReactUniversalClientLoader function ReactUniversalClientLoader(source, map) { - const filename = relative(this.options.context, this.resourcePath) + const filename = relative(this.rootContext, this.resourcePath) const importPath = relative(this.context, this.resourcePath) const id = filename.replace(/[/.]/g, '_') return createClientCode({ importPath, id }) diff --git a/library/webpack-loaders/react-universal-server-loader.js b/library/webpack-loaders/react-universal-server-loader.js index 48678c97..f7359ba8 100644 --- a/library/webpack-loaders/react-universal-server-loader.js +++ b/library/webpack-loaders/react-universal-server-loader.js @@ -3,7 +3,7 @@ const { relative } = require('path') module.exports = ReactUniversalServerLoader function ReactUniversalServerLoader(source, map) { - const filename = relative(this.options.context, this.resourcePath) + const filename = relative(this.rootContext, this.resourcePath) const importPath = relative(this.context, this.resourcePath) const id = filename.replace(/[/.]/g, '_') return createServerCode({ importPath, id, filename }) diff --git a/library/webpack-loaders/to-json-file-loader.js b/library/webpack-loaders/to-json-file-loader.js index 4bf31589..b820425f 100644 --- a/library/webpack-loaders/to-json-file-loader.js +++ b/library/webpack-loaders/to-json-file-loader.js @@ -5,7 +5,7 @@ const { relative } = require('path') module.exports = function ToJsonFileLoader(source) { - const filename = relative(this.options.context, this.resourcePath) + const filename = relative(this.rootContext, this.resourcePath) this.emitFile(filename + '.json', JSON.stringify(source)) return '// json file was emitted' } diff --git a/library/webpack-plugins/chunk-manifest-plugin.js b/library/webpack-plugins/chunk-manifest-plugin.js index b3feae2b..c5b79447 100644 --- a/library/webpack-plugins/chunk-manifest-plugin.js +++ b/library/webpack-plugins/chunk-manifest-plugin.js @@ -16,25 +16,35 @@ */ const { RawSource } = require('webpack-sources') +const { SyncHook } = require('tapable') + +const p = 'chunk-manifest-plugin' module.exports = function chunkManifestPlugin() { return { apply: compiler => { - compiler.plugin('compilation', compilation => { - const chunkAssets = {} + compiler.hooks.compilation.tap(p, compilation => { + compilation.hooks.chunkManifest = new SyncHook(['chunkAssets']) - compilation.plugin('chunk-asset', (chunk, filename) => { + const chunkAssets = {} + compilation.hooks.chunkAsset.tap(p, (chunk, filename) => { if (!chunk.name || filename.includes('hot-update')) return + + const groups = [...chunk.groupsIterable] + const isShared = groups.length > 1 + const [group] = groups + chunkAssets[chunk.name] = { filename, hasRuntime: chunk.hasRuntime(), - parents: chunk.parents.map(c => c.name).filter(Boolean) + isShared, + ...(!isShared && { dependencies: group.chunks.filter(x => x !== chunk).map(x => x.name) }) } }) - compilation.plugin('additional-chunk-assets', chunks => { - compilation.applyPlugins('chunk-manifest', chunkAssets) + compilation.hooks.additionalChunkAssets.tap(p, chunks => { + compilation.hooks.chunkManifest.call(chunkAssets) compilation.assets['chunk-manifest.json'] = new RawSource(JSON.stringify(chunkAssets, null, 2)) }) }) diff --git a/library/webpack-plugins/config-loader-plugin.js b/library/webpack-plugins/config-loader-plugin.js index e4e29789..6146dcce 100644 --- a/library/webpack-plugins/config-loader-plugin.js +++ b/library/webpack-plugins/config-loader-plugin.js @@ -1,12 +1,14 @@ /* This plugin determines when @kaliber/config is imported and pushes the custom config-loader */ +const p = 'config-loader-plugin' + module.exports = function configLoaderPlugin() { return { apply: compiler => { - compiler.plugin('normal-module-factory', normalModuleFactory => { + compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.plugin('after-resolve', (data, done) => { + normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { const { loaders, rawRequest } = data if (rawRequest === '@kaliber/config') diff --git a/library/webpack-plugins/copy-unused-files-plugin.js b/library/webpack-plugins/copy-unused-files-plugin.js index 13bac4b6..69144116 100644 --- a/library/webpack-plugins/copy-unused-files-plugin.js +++ b/library/webpack-plugins/copy-unused-files-plugin.js @@ -6,11 +6,13 @@ const fs = require('fs-extra') const path = require('path') const walkSync = require('walk-sync') +const p = 'copy-unused-files-plugin' + module.exports = function copyUnusedFilesPlugin() { return { apply: compiler => { - compiler.plugin('after-emit', (compilation, done) => { + compiler.hooks.afterEmit.tapAsync(p, (compilation, done) => { const context = compiler.context @@ -26,7 +28,7 @@ module.exports = function copyUnusedFilesPlugin() { walkSync(context).map(filePath => { const source = path.resolve(context, filePath) - if (compilation.fileDependencies.includes(source)) return null + if (compilation.fileDependencies.has(source)) return null const target = path.resolve(compiler.options.output.path, filePath) return stat(source) diff --git a/library/webpack-plugins/hot-css-replacement-plugin.js b/library/webpack-plugins/hot-css-replacement-plugin.js index f1c9853e..d43a0c87 100644 --- a/library/webpack-plugins/hot-css-replacement-plugin.js +++ b/library/webpack-plugins/hot-css-replacement-plugin.js @@ -4,6 +4,8 @@ */ const ansiRegex = require('ansi-regex') +const p = 'hot-css-replacement-plugin' + module.exports = function hotCssReplacementPlugin() { return { @@ -11,19 +13,19 @@ module.exports = function hotCssReplacementPlugin() { let send let cssChunkHashes - compiler.plugin('websocket-send-available', x => { send = x }) + compiler.hooks.websocketSendAvailable.tap(p, x => { send = x }) - compiler.plugin('compilation', compilation => { + compiler.hooks.compilation.tap(p, compilation => { cssChunkHashes = {} - compilation.plugin('chunk-css-hashes', (chunkName, cssHashes) => { + compilation.hooks.chunkCssHashes.tap(p, (chunkName, cssHashes) => { cssChunkHashes[chunkName] = cssHashes }) }) - compiler.plugin('done', stats => { + compiler.hooks.done.tap(p, stats => { if (stats.hasErrors()) sendErrors(stats.toJson('errors-only').errors) else send({ type: 'done', hash: stats.hash, cssChunkHashes }) }) - compiler.plugin('failed', err => { sendErrors([err.message]) }) + compiler.hooks.failed.tap(p, err => { sendErrors([err.message]) }) function sendErrors(errors) { send({ type: 'failed', errors: errors.map(e => e.replace(ansiRegex(), '')) }) diff --git a/library/webpack-plugins/hot-module-replacement-plugin.js b/library/webpack-plugins/hot-module-replacement-plugin.js index 6af22a2d..b01b5a13 100644 --- a/library/webpack-plugins/hot-module-replacement-plugin.js +++ b/library/webpack-plugins/hot-module-replacement-plugin.js @@ -7,6 +7,8 @@ const webpack = require('webpack') const ansiRegex = require('ansi-regex') +const p = 'hot-module-replacement-plugin' + module.exports = function hotModuleReplacementPlugin() { return { @@ -15,12 +17,12 @@ module.exports = function hotModuleReplacementPlugin() { let send - compiler.plugin('websocket-send-available', x => { send = x }) - compiler.plugin('done', stats => { + compiler.hooks.websocketSendAvailable.tap(p, x => { send = x }) + compiler.hooks.done.tap(p, stats => { if (stats.hasErrors()) sendErrors(stats.toJson('errors-only').errors) else send({ type: 'done', hash: stats.hash }) }) - compiler.plugin('failed', err => { sendErrors([err.message]) }) + compiler.hooks.failed.tap(p, err => { sendErrors([err.message]) }) function sendErrors(errors) { send({ type: 'failed', errors: errors.map(e => e.replace(ansiRegex(), '')) }) diff --git a/library/webpack-plugins/make-additional-entries-plugin.js b/library/webpack-plugins/make-additional-entries-plugin.js index 294d206d..3f23e0f3 100644 --- a/library/webpack-plugins/make-additional-entries-plugin.js +++ b/library/webpack-plugins/make-additional-entries-plugin.js @@ -9,7 +9,7 @@ Usage from other plugins: - compiler.plugin('make-additional-entries', (compilation, createEntries, done) => { + compiler.hooks.makeAdditionalEntries.tapAsync('plugin-name', (compilation, createEntries, done) => { // if you want to add new entries createEntries({ name: path }, done) @@ -23,34 +23,40 @@ and - compiler.plugin('claim-entries', entries => { + compiler.hooks.claimEntries.tap('plugin-name', entries => { return unclaimedEntries }) */ +const { AsyncSeriesHook, SyncWaterfallHook } = require('tapable') const SingleEntryDependency = require('webpack/lib/dependencies/SingleEntryDependency') const { createDependency } = require('webpack/lib/SingleEntryPlugin') +const p = 'make-additional-entries' + module.exports = function makeAdditionalEntries() { return { apply: compiler => { + compiler.hooks.claimEntries = new SyncWaterfallHook(['entries']) + compiler.hooks.makeAdditionalEntries = new AsyncSeriesHook(['compilation', 'createEntries']) + const entriesToMake = {} /* claim the entries in the `entry` if it's object shaped and allow other plugins to claim certain entries, any leftover entries are added using this plugin */ - compiler.plugin('entry-option', (context, entries) => { + compiler.hooks.entryOption.tap(p, (context, entries) => { if (typeof entries === 'object' && !Array.isArray(entries)) { const originalEntries = Object.assign({}, entries) - Object.assign(entriesToMake, compiler.applyPluginsWaterfall('claim-entries', originalEntries)) + Object.assign(entriesToMake, compiler.hooks.claimEntries.call(originalEntries)) return true } }) // make sure the SingleEntryDependency has a factory - compiler.plugin('compilation', (compilation, { normalModuleFactory }) => { + compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set(SingleEntryDependency, normalModuleFactory) }) @@ -59,7 +65,7 @@ module.exports = function makeAdditionalEntries() { Note that plugins can depend on entries created in plugins registered before them. */ - compiler.plugin('make', (compilation, done) => { + compiler.hooks.make.tapAsync(p, (compilation, done) => { addEntries(entriesToMake) .then(makeAdditionalEntries) @@ -68,8 +74,7 @@ module.exports = function makeAdditionalEntries() { function makeAdditionalEntries() { return new Promise((resolve, reject) => { - compiler.applyPluginsAsyncSeries( - 'make-additional-entries', + compiler.hooks.makeAdditionalEntries.callAsync( compilation, (entries, done) => { addEntries(entries || {}).then(_ => { done() }).catch(done) }, err => { err ? reject(err) : resolve() } @@ -84,7 +89,7 @@ module.exports = function makeAdditionalEntries() { function addEntry(name, path) { return new Promise((resolve, reject) => { const entry = createDependency(path, name) - compilation.addEntry(compiler.context, entry, entry.loc, err => err ? reject(err) : resolve()) + compilation.addEntry(compiler.context, entry, name, err => err ? reject(err) : resolve()) }) } }) diff --git a/library/webpack-plugins/merge-css-plugin.js b/library/webpack-plugins/merge-css-plugin.js index db472b1d..b93c1494 100644 --- a/library/webpack-plugins/merge-css-plugin.js +++ b/library/webpack-plugins/merge-css-plugin.js @@ -6,9 +6,9 @@ This plugin makes the __webpack_css_chunk_hash__ variable available to get the hash of the css that is linked from the current chunk. - It also adds a 'chunk-css-hashes' hook which can be used by plugins to record the css hash of a chunk: + It also adds a 'chunkCssHashes' hook which can be used by plugins to record the css hash of a chunk: - compilation.plugin('chunk-css-hashes', (chunkName, cssHashes) => { + compilation.hooks.chunkCssHashes.tap('plugin-name', (chunkName, cssHashes) => { ... }) */ @@ -18,23 +18,28 @@ const NullFactory = require('webpack/lib/NullFactory') const ParserHelpers = require('webpack/lib/ParserHelpers') const crypto = require('crypto') const { ConcatSource, RawSource } = require('webpack-sources') +const { SyncHook } = require('tapable') + +const p = 'merge-css-plugin' module.exports = function mergeCssPlugin() { return { apply: compiler => { - compiler.plugin('compilation', (compilation, { normalModuleFactory }) => { + compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { + + compilation.hooks.chunkCssHashes = new SyncHook(['chunkName', 'cssHashes']) const newChunksWithCssAssets = {} const chunkCssHashes = new Map() // extract css assets - compilation.plugin('before-module-assets', () => { + compilation.hooks.beforeModuleAssets.tap(p, () => { const cssAssetChunks = {} // determine all css assets and record the chunks they're used in compilation.chunks.forEach(chunk => { const modules = chunk.getModules().sort(({ index: a }, { index: b }) => a - b) - modules.forEach(({ assets = {} }) => { + modules.forEach(({ buildInfo: { assets = {} } }) => { Object.keys(assets).filter(x => x.endsWith('.css')).forEach(assetName => { const chunks = cssAssetChunks[assetName] if (chunks) chunks.push(chunk) @@ -64,7 +69,7 @@ module.exports = function mergeCssPlugin() { */ // remove assets that will be merged and add a hash and the actual assets // to the new chunks - compilation.plugin('before-chunk-assets', () => { + compilation.hooks.beforeChunkAssets.tap(p, () => { const assetsToRemove = [] Object.keys(newChunksWithCssAssets).forEach(chunkName => { @@ -94,14 +99,14 @@ module.exports = function mergeCssPlugin() { .map(({ cssHash }) => cssHash) chunkCssHashes.set(chunk, cssHashes) - compilation.applyPlugins('chunk-css-hashes', chunk.name, cssHashes) + compilation.hooks.chunkCssHashes.call(chunk.name, cssHashes) }) }) // make sure the __webpack_css_chunk_hashes__ is available in modules (code copied from ExtendedApiPlugin) compilation.dependencyFactories.set(ConstDependency, new NullFactory()) compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.plugin('require-extensions', function(source, chunk, hash) { + compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { const cssHashes = chunkCssHashes.get(chunk) || [] @@ -109,22 +114,25 @@ module.exports = function mergeCssPlugin() { source, '', '// __webpack_css_chunk_hashes__', - `${this.requireFn}.cch = ${JSON.stringify(cssHashes)};` + `${compilation.mainTemplate.requireFn}.cch = ${JSON.stringify(cssHashes)};` ] - return this.asString(buf) - }) - compilation.mainTemplate.plugin('global-hash', () => true) - normalModuleFactory.plugin('parser', (parser, parserOptions) => { - parser.plugin(`expression __webpack_css_chunk_hashes__`, ParserHelpers.toConstantDependency('__webpack_require__.cch')) - parser.plugin(`evaluate typeof __webpack_css_chunk_hashes__`, ParserHelpers.evaluateToString('string')) + return buf.join('\n') }) + compilation.mainTemplate.hooks.globalHash.tap(p, () => true) + normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) + normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) + + function addParserHooks(parser, parserOptions) { + parser.hooks.expression.for(`__webpack_css_chunk_hashes__`).tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.cch')) + parser.hooks.evaluateTypeof.for(`__webpack_css_chunk_hashes__`).tap(p, ParserHelpers.evaluateToString('string')) + } // merge css assets - compilation.plugin('additional-chunk-assets', chunks => { + compilation.hooks.additionalChunkAssets.tap(p, chunks => { // remove any css entry chunk assets chunks.forEach(({ name }) => { - if (name.endsWith('.css')) delete compilation.assets[name] + if (name && name.endsWith('.css')) delete compilation.assets[name] }) // create a manifest diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index 6571532a..e1a36175 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -8,6 +8,7 @@ const Stats = require('webpack/lib/Stats') const WebpackOptionsApply = require('webpack/lib/WebpackOptionsApply') const { ReplaceSource } = require('webpack-sources') const { relative } = require('path') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') /* @@ -18,6 +19,8 @@ const { relative } = require('path') - add the client loader to those modules */ +const p = 'react-universal-plugin' + // works only when entry is an object module.exports = function reactUniversalPlugin () { @@ -28,31 +31,31 @@ module.exports = function reactUniversalPlugin () { const webCompiler = createWebCompiler(compiler, () => clientEntries) - // when the webCompiler starts compiling add the recorded client entries - webCompiler.plugin('make-additional-entries', (compilation, createEntries, done) => { + // // when the webCompiler starts compiling add the recorded client entries + webCompiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, createEntries, done) => { createEntries(clientEntries, done) }) // check the parent compiler before creating a module, it might have already // been processed let compilation - compiler.plugin('compilation', c => { compilation = c }) - webCompiler.plugin('compilation', (webCompilation, { normalModuleFactory }) => { - normalModuleFactory.plugin('create-module', data => { - if (!data.resourceResolveData.path.endsWith('.js')) { + compiler.hooks.compilation.tap(p, c => { compilation = c }) + webCompiler.hooks.compilation.tap(p, (webCompilation, { normalModuleFactory }) => { + normalModuleFactory.hooks.createModule.tap(p, data => { + const path = data.resourceResolveData.path + if (!path.endsWith('.js') && !path.endsWith('.json')) { const parentCompilationModule = compilation.findModule(data.request) if (parentCompilationModule) { // mutation in webpack internals is a minefield, tread carefully const dependencies = parentCompilationModule.dependencies.slice() const parentSource = new ReplaceSource(parentCompilationModule.originalSource()) - const { dependencyTemplates, outputOptions, moduleTemplate: { requestShortener } } = webCompilation + const { dependencyTemplates, outputOptions, moduleTemplates: { javascript: { requestShortener } } } = webCompilation // from NormalModule.sourceDependency dependencies.forEach(dependency => { const template = dependencyTemplates.get(dependency.constructor) - if(!template) throw new Error('No template for dependency: ' + dependency.constructor.name) - template.apply(dependency, parentSource, outputOptions, requestShortener, dependencyTemplates) + if (template) template.apply(dependency, parentSource, outputOptions, requestShortener, dependencyTemplates) }) const result = new RawModule(parentSource.source()) @@ -64,14 +67,14 @@ module.exports = function reactUniversalPlugin () { }) // before we compile, make sure the timestamps (important for caching and changed by watch) are updated - compiler.plugin('before-compile', (params, done) => { + compiler.hooks.beforeCompile.tapAsync(p, (params, done) => { webCompiler.fileTimestamps = compiler.fileTimestamps webCompiler.contextTimestamps = compiler.contextTimestamps done() }) // we claim entries ending with `entry.js` and record them as client entries for the web compiler - compiler.plugin('claim-entries', entries => { + compiler.hooks.claimEntries.tap(p, entries => { const [claimed, unclaimed] = Object.keys(entries).reduce( ([claimed, unclaimed], name) => { const entry = entries[name] @@ -95,9 +98,9 @@ module.exports = function reactUniversalPlugin () { When a module marked with `?universal` has been resolved, add the `react-universal-server-loader` to it's loaders and add the module marked with `?universal-client` as client entry. */ - compiler.plugin('normal-module-factory', normalModuleFactory => { + compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.plugin('before-resolve', (data, done) => { + normalModuleFactory.hooks.beforeResolve.tapAsync(p, (data, done) => { if (!data) return done(null, data) if (data.dependencies.some(x => x instanceof ImportDependency)) return done() @@ -105,7 +108,7 @@ module.exports = function reactUniversalPlugin () { done(null, data) }) - normalModuleFactory.plugin('after-resolve', (data, done) => { + normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { const { loaders, resourceResolveData: { query, path } } = data if (query === '?universal') { @@ -120,7 +123,7 @@ module.exports = function reactUniversalPlugin () { }) // tell the web compiler to compile, emit the assets and notify the appropriate plugins - compiler.plugin('make-additional-entries', (compilation, createEntries, done) => { + compiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, createEntries, done) => { const startTime = Date.now() webCompiler.compile((err, webCompilation) => { @@ -137,7 +140,7 @@ module.exports = function reactUniversalPlugin () { function finish(err, compilation) { if (err) { - webCompiler.applyPlugins('failed', err) + webCompiler.hooks.failed.call(err) return done(err) } @@ -145,17 +148,15 @@ module.exports = function reactUniversalPlugin () { stats.startTime = startTime stats.endTime = Date.now() - webCompiler.applyPlugins('done', stats) - - done() + webCompiler.hooks.done.callAsync(stats, done) } }) // make sure the __webpack_js_chunk_information__ is available in modules (code copied from ExtendedApiPlugin) - compiler.plugin('compilation', (compilation, { normalModuleFactory }) => { + compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set(ConstDependency, new NullFactory()) compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.plugin('require-extensions', function(source, chunk, hash) { + compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { // get the manifest from the client compilation const [{ _kaliber_chunk_manifest_: manifest }] = compilation.children @@ -169,15 +170,18 @@ module.exports = function reactUniversalPlugin () { source, '', '// __webpack_js_chunk_information__', - `${this.requireFn}.jci = ${JSON.stringify({ universalChunkNames, manifest })};` + `${compilation.mainTemplate.requireFn}.jci = ${JSON.stringify({ universalChunkNames, manifest })};` ] - return this.asString(buf) - }) - compilation.mainTemplate.plugin('global-hash', () => true) - normalModuleFactory.plugin('parser', (parser, parserOptions) => { - parser.plugin(`expression __webpack_js_chunk_information__`, ParserHelpers.toConstantDependency('__webpack_require__.jci')) - parser.plugin(`evaluate typeof __webpack_js_chunk_information__`, ParserHelpers.evaluateToString('array')) + return buf.join('\n') }) + compilation.mainTemplate.hooks.globalHash.tap(p, () => true) + normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) + normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) + + function addParserHooks(parser, parserOptions) { + parser.hooks.expression.for('__webpack_js_chunk_information__').tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.jci')) + parser.hooks.evaluateTypeof.for('__webpack_js_chunk_information__').tap(p, ParserHelpers.evaluateToString('array')) + } }) } } @@ -185,6 +189,9 @@ module.exports = function reactUniversalPlugin () { function createWebCompiler(compiler, getEntries) { + // TODO we need to use another mechanism so that we can set the options + // in the build.js and also we need to use the optiondefaulter from webpack + // Massage the options to become a web configuration const options = Object.assign({}, compiler.options) options.name = 'react-universal-plugin-client-compiler' @@ -195,6 +202,36 @@ function createWebCompiler(compiler, getEntries) { options.output = Object.assign({}, options.output) options.output.libraryTarget = 'var' options.output.filename = '[id].[hash].js' + options.output.chunkFilename = '[id].[hash].js' + options.output.globalObject = 'window' + + options.optimization = Object.assign({}, options.optimization) + options.optimization.runtimeChunk = 'single' + options.optimization.minimize = options.mode === 'production' + options.optimization.minimizer = [ + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap: true // this one is important + }) + ] + options.optimization.splitChunks = { + chunks: 'all', + minSize: 10000, + minChunks: 1, + maxAsyncRequests: 5, + automaticNameDelimiter: '~', + maxInitialRequests: 3, + name: true, + filename: '[id].[hash].js', + cacheGroups: { + default: { + reuseExistingChunk: true, + minChunks: 2, + priority: -20 + } + } + } options.resolve = Object.assign({}, options.resolve) options.resolve.aliasFields = ['browser'] @@ -210,8 +247,8 @@ function createWebCompiler(compiler, getEntries) { provide a friendly error if @kaliber/config is loaded from a client module */ - webCompiler.plugin('normal-module-factory', normalModuleFactory => { - normalModuleFactory.plugin('after-resolve', (data, done) => { + webCompiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { + normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { const { loaders, rawRequest, resourceResolveData: { query } } = data if (query === '?universal-client') @@ -225,8 +262,8 @@ function createWebCompiler(compiler, getEntries) { }) // make the chunk manifest available - webCompiler.plugin('compilation', compilation => { - compilation.plugin('chunk-manifest', chunkManifest => { + webCompiler.hooks.compilation.tap(p, compilation => { + compilation.hooks.chunkManifest.tap(p, chunkManifest => { compilation._kaliber_chunk_manifest_ = chunkManifest }) }) @@ -235,9 +272,9 @@ function createWebCompiler(compiler, getEntries) { } function createCompiler(compiler, options) { - const childCompiler = new Compiler() + const childCompiler = new Compiler(options.context) - /* from webpack.js */ + /* from lib/webpack.js */ childCompiler.context = options.context childCompiler.options = options @@ -246,9 +283,10 @@ function createCompiler(compiler, options) { childCompiler.outputFileSystem = compiler.outputFileSystem childCompiler.watchFileSystem = compiler.watchFileSystem - childCompiler.apply.apply(childCompiler, options.plugins) - childCompiler.applyPlugins('environment') - childCompiler.applyPlugins('after-environment') + options.plugins.forEach(plugin => { plugin.apply(childCompiler) }) + childCompiler.hooks.environment.call() + childCompiler.hooks.afterEnvironment.call() + childCompiler.options = new WebpackOptionsApply().process(options, childCompiler) return childCompiler diff --git a/library/webpack-plugins/shared-modules-plugin.js b/library/webpack-plugins/shared-modules-plugin.js deleted file mode 100644 index 3cc7df64..00000000 --- a/library/webpack-plugins/shared-modules-plugin.js +++ /dev/null @@ -1,374 +0,0 @@ -/* - In a few steps, this is what the plugin does: - - 1. Gather all modules that are used in multiple chunks record the chunks that use the module - - 2. Determine all the chunks that need to be created and the modules that should be in those chunks - - 3. Remove any chunks smaller than a given size - - 4. a. Create new Chunks - b. Move the modules into those chunks - c. Adjust the chunk hierarchy - d. Remove runtimes - - 5. Make sure the correct chunks get a runtime - - - ps. If you want to know more about entrypoints and runtimes, look at the end of this document. -*/ - -module.exports = function sharedModulesPlugin() { - - return { - apply: compiler => { - compiler.plugin('compilation', compilation => { - - compilation.plugin('optimize-chunks', chunks => { - - const moduleUsage = determineModuleUsage(chunks) - /* - moduleUsage = Map( - [module]: [chunk1, ..., chunkN] - ) - */ - - const newChunkInfo = determineNewChunks(moduleUsage) - /* - newChunkInfo = { - 'newChunkName': { - chunks: [chunk1, ..., chunkN], - modules: [module1, ..., moduleN] - } - } - */ - - removeSmallChunks(newChunkInfo, { minSize: 10000 /* 10K */ }) - - const newChunks = addChunks(compilation, Object.keys(newChunkInfo)) - newChunks.forEach(newChunk => { - - const { chunks, modules } = newChunkInfo[newChunk.name] - - moveModules(modules, { sources: chunks, target: newChunk }) - - createHierarchy({ parent: newChunk, children: chunks }) - - removeRuntimes(chunks) - }) - - if (newChunks.length) { - // we could use this instead of the `addRuntimes` function - // const runtimeChunk = addChunk(compilation, 'shared runtime', { addRuntime: true }) - // createHierarchy({ parent: runtimeChunk, children: newChunks }) - - addRuntimes(compilation, newChunks) - - doubleCheckRuntimes(newChunks) - } - - return false - }) - }) - } - } -} - -function determineModuleUsage(chunks) { - return chunks.reduce( - (result, chunk) => { - chunk.getModules().forEach(module => { - const chunks = result.get(module) - if (chunks) chunks.push(chunk) - else result.set(module, [chunk]) - }) - return result - }, - new Map() - ) -} - -function determineNewChunks(moduleUsage) { - return Array.from(moduleUsage.entries()).reduce( - (result, [module, chunks]) => { - if (chunks.length === 1) return result // ignore modules that are included in only one chunk - - const newChunkName = `shared (${chunks.map(c => c.name).join(', ')})` - - const chunkInfo = result[newChunkName] - if (chunkInfo) { - chunkInfo.modules.push(module) - chunkInfo.size += module.size() - } else result[newChunkName] = { chunks, modules: [module], size: module.size() } - - return result - }, - {} - ) -} - -function removeSmallChunks(newChunkInfo, { minSize }) { - Object.keys(newChunkInfo).forEach(newChunkName => { - const { size } = newChunkInfo[newChunkName] - - if (size < minSize) delete newChunkInfo[newChunkName] - }) -} - -function addChunks(compilation, chunkNames) { - return chunkNames.map(chunkName => - addChunk(compilation, chunkName, { addRuntime: false }) - ) -} - -function addChunk(compilation, name, { addRuntime }) { - const newChunk = compilation.addChunk(name) - newChunk.filenameTemplate = '[id].[hash].js' - newChunk.entrypoints = [{ chunks: addRuntime ? [newChunk] : [] }] // no runtime in this chunk - return newChunk -} - -function moveModules(modules, { sources, target }) { - modules.forEach(module => { - sources.forEach(chunk => { chunk.removeModule(module) }) - target.addModule(module) - module.addChunk(target) - }) -} - -function createHierarchy({ parent, children }) { - children.forEach(chunk => { - chunk.addParent(parent) - parent.addChunk(chunk) - }) -} - -function removeRuntimes(chunks) { - chunks.forEach(chunk => { - chunk.entrypoints.forEach(entrypoint => { - entrypoint.chunks.length = 0 // prevent the chunk from including a runtime - }) - }) -} - -function addRuntimes(compilation, newChunks) { - if (newChunks.length === 1) return addRuntime(newChunks[0]) - - const affectedChunks = determineAffectedChunks(newChunks) - /* - affectedChunks = Map( - [chunk]: [newChunk1, ..., newChunkN] - ) - */ - - const chunkWithAllChunks = newChunks.find(({ chunks }) => chunks.length === affectedChunks.size) - if (chunkWithAllChunks) return addRuntime(chunkWithAllChunks) - - - const { exclusive, shared } = determineCoverage(newChunks, affectedChunks) - exclusive.forEach(addRuntime) - - if (!shared.length) return - - const runtimeChunkName = `shared runtime (${shared.map(c => c.name).join(', ')})` - const runtimeChunk = addChunk(compilation, runtimeChunkName, { addRuntime: true }) - createHierarchy({ parent: runtimeChunk, children: shared }) -} - -function addRuntime(chunk) { - chunk.entrypoints = [{ chunks: [chunk] }] -} - -function determineAffectedChunks(newChunks) { - return newChunks.reduce( - (result, newChunk) => { - newChunk.chunks.forEach(chunk => { - const newChunks = result.get(chunk) - if (newChunks) newChunks.push(newChunk) - else result.set(chunk, [newChunk]) - }) - return result - }, - new Map() - ) -} - -function determineCoverage(newChunks, affectedChunks) { - const shareCount = determineShareCounts(newChunks, affectedChunks) - /* - shareCount = Map( - [newChunk]: 0 - ) - */ - - return newChunks.reduce( - ({ exclusive, shared }, newChunk) => { - const isExclusive = shareCount.get(newChunk) === 1 - - if (isExclusive) exclusive.push(newChunk) - else shared.push(newChunk) - - return { exclusive, shared } - }, - { exclusive: [], shared: [] } - ) -} - -function determineShareCounts(newChunks, affectedChunks) { - return Array.from(affectedChunks.values()).reduce( - (result, newChunks) => { - newChunks.forEach(newChunk => { - const previousShareCount = result.get(newChunk) || 0 - const newShareCount = newChunks.length - - if (newShareCount > previousShareCount) result.set(newChunk, newShareCount) - }) - return result - }, - new Map() - ) -} - -/* - This function is not strictly necessary but allows us to, more easily catch edge cases - and changes to the webpack internals. - - With this function we check if each original chunk that was affected by this module - has exactly 1 runtime in it's 'chunk-chain' -*/ -function doubleCheckRuntimes(newChunks) { - const affectedChunks = determineAffectedChunks(newChunks) - /* - affectedChunks = Map( - [chunk]: [newChunk1, ..., newChunkN] - ) - */ - Array.from(affectedChunks.entries()).forEach( - ([chunk, newChunks]) => { - - if (chunk.hasRuntime()) error( - `|Optimized chunk (${chunk.name}) has a runtime while it uses ${newChunks.length} shared chunks` - ) - - const newChunksWithRuntime = newChunks.filter(newChunk => newChunk.hasRuntime()) - if (newChunksWithRuntime > 1) error( - `|More than one shared chunk (used by a single chunk), ${newChunksWithRuntime.length} to be exact, - |has a runtime: - |${newChunksWithRuntime.map(c => c.name).join(', ')}` - ) - - if (newChunksWithRuntime === 0) { - newChunks.reduce( - (previousParent, { name, parent }) => { - - if (!parent.hasRuntime()) error( - `|Shared chunk (${name}) does not have a runtime and it's parent (${parent.name}) does not have - |one either.` - ) - - if (previousParent && previousParent !== parent) error( - `|Shared chunk (${name}) does not have a runtime and it's parent (${parent.name}) is different - |from the parent of the previous shared chunk (${previousParent.name}). This means the chunk (${chunk.name}) - |has more than one runtime.` - ) - - return parent - }, - null - ) - } - } - ) - - function error(message) { - throw new Error( - `|You have found an implementation problem in the CommonChunksPlugin of @kaliber/build. - |This error means one of two things: - |- Webpack has changed it's internals and we need to check the changes to make this plugin - | work again. - |- You have found a situation that we did not foresee when writing this plugin - | - |* In both cases it would be awesome if you were to create an issue. * - | - |Extra information for the developers: - ${message} - |`.split(/^[ \t]*\|/m).join('') - ) - } -} - -/* - Chunks, entrypoints and the runtime. - ------------------------------------ - - This is a tricky topic (mainly because of the weird implementation) so I'll write it down in hopes I - will understand it. - - There is this concept of 'preparedChunks' in the compilation. These are filled by calls to `addEntry` - which is done during the `make` phase (by for example the `entry` configuration). - - During the `seal` phase these `preparedChunks` are converted into chunks (by `addChunk`). At this point - an `Entrypoint` with the name of the chunk is created. And the chunk is 'unshifted' into the entrypoint. - 'unshift' here means: - - add the chunk at the front of the chunks array of the entry point - - add the entry point at the end of the entrypoints of the chunk - - So, once this is done we have the following structure: - - Chunk #1 - - name: 'somename' - - entrypoints: [ - Entrypoint #1 - - name: 'somename', - - chunks: [Chunk #1] - ] - - If you would ask this chunk: do you have a runtime? It would say: yes, because I am the first chunk in - the first entrypoint. - - If you would ask this chunk: are you initial? It would say: yes, because I have entrypoints - - Oh, the use of initial is a bit unclear, it seems to have an effect on the file name if the chunk has no - `filenameTemplate`. If this is the case, initial means use the outputOptions.filename otherwise use - outputOptions.chunkFilename. - - If a chunk has a runtime it means it's rendered using the main template instead of the chunk template. This - however does not guarantee a runtime (also called bootstrap internally). There is one more thing required - for a chunk to be rendered with a runtime: chunk.chunks must have at least one chunk. These are added to the - chunk using the `addChunk` method in `Chunk`. To me it's unclear when this happens with with 'normal' chunks. - - Anyway, from the CommonsChunkPlugin I learned which steps to take in order move around modules between chunks. - - 1. Gather the modules that need to be moved - 2. Create a chunk to move them to - 3. Move the module (parent/child relation) - 4. Connect the chunks (parent/child relation) - 5. Adjust the entrypoints - - 1, 2, 3* and 4** are fairly sraightforward. - - * Moving a module to a chunk is a three step process: - 1. Remove the module from a chunk - 2. Add the module to a chunk - 3. Add the chunk to a module - - ** Adding a chunk(1) to a chunk(2) is a two step process, my guess is that this is used to signal a dependency: - 1. Add the chunk(2) as a parent to the chunk(1) - 2. Add a chunk(1) to the chunk(2) - - 5 on the other other hand is kinda tricky. Entrypoints seem to be only used to determine if a chunk is initial - or if it has a runtime. The CommonsChunkPlugin calls `insertChunk` on each entrypoint it stole modules from. - This has the effect that it will appear as the first chunk in the entrypoints of the chunk that the modules were - stolen from and that the entrypoint itself is added to the chunk. Yeah I know: mindboggling. - - Netto effect is that the newly created chunk has an entry point with itself as a first chunk (a runtime) and making - sure the chunk it stole modules from is no longer the first entry point (no runtime). If a core member of the - webpack team ever reads this: Please, refactor this stuff, it makes watching at the clock and understanding what time - it is while under the influence of magic mushrooms look easy. - - In any case instead of using the magical `insertChunk` method, we could probably just `unshift` any value into the - chunks property of the entry point, or even clear the chunks of the entry point. - - The entry point in the newly created chunk can just contain the chunk itself if it needs a runtime, if not it can be - an array like this `[{ chunks: [] }]` to make sure it's initial. -*/ diff --git a/library/webpack-plugins/source-map-plugin.js b/library/webpack-plugins/source-map-plugin.js index a98f1692..0c73d0b5 100644 --- a/library/webpack-plugins/source-map-plugin.js +++ b/library/webpack-plugins/source-map-plugin.js @@ -6,18 +6,20 @@ const { RawSource, ConcatSource } = require('webpack-sources') const path = require('path') +const p = 'source-map-plugin' + module.exports = function sourceMapPlugin() { return { apply: compiler => { - compiler.plugin('compilation', compilation => { + compiler.hooks.compilation.tap(p, compilation => { // make sure webpack stuff keeps their source maps - compilation.plugin('build-module', module => { + compilation.hooks.buildModule.tap(p, module => { module.useSourceMap = true }) // add source map assets for anything that still has one - compilation.plugin('after-optimize-assets', assets => { + compilation.hooks.afterOptimizeAssets.tap(p, assets => { Object.keys(assets).forEach(name => { const asset = assets[name] const map = asset.map() diff --git a/library/webpack-plugins/target-based-plugins-plugin.js b/library/webpack-plugins/target-based-plugins-plugin.js index dada5463..e15a395f 100644 --- a/library/webpack-plugins/target-based-plugins-plugin.js +++ b/library/webpack-plugins/target-based-plugins-plugin.js @@ -12,9 +12,11 @@ module.exports = function targetBasedPluginsPlugin(plugins) { return { apply: compiler => { - compiler.apply.apply(compiler, plugins.all) + plugins.all.forEach(applyPlugin) const targetPlugins = plugins[compiler.options.target] - if (targetPlugins) compiler.apply.apply(compiler, targetPlugins) + if (targetPlugins) targetPlugins.forEach(applyPlugin) + + function applyPlugin(plugin) { plugin.apply(compiler) } } } } diff --git a/library/webpack-plugins/template-plugin.js b/library/webpack-plugins/template-plugin.js index a878eff2..bfe18639 100644 --- a/library/webpack-plugins/template-plugin.js +++ b/library/webpack-plugins/template-plugin.js @@ -20,6 +20,8 @@ const { RawSource } = require('webpack-sources') const { basename } = require('path') const { evalWithSourceMap, withSourceMappedError } = require('../lib/node-utils') +const p = 'template-plugin' + module.exports = function templatePlugin(renderers) { const templatePattern = /\.([^./]+)\.js$/ // {name}.{template type}.js @@ -49,8 +51,8 @@ module.exports = function templatePlugin(renderers) { file name. It will not do this to resources that have been marked with `?template-source` as it would cause infinite loops */ - compiler.plugin('normal-module-factory', normalModuleFactory => { - normalModuleFactory.plugin('after-resolve', (data, done) => { + compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { + normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { const { loaders, resourceResolveData: { query, path } } = data const renderInfo = getRenderInfo(path) @@ -64,7 +66,7 @@ module.exports = function templatePlugin(renderers) { }) }) - compiler.plugin('compilation', compilation => { + compiler.hooks.compilation.tap(p, compilation => { /* Determines if a given asset has the 'template pattern' and if so it @@ -79,7 +81,7 @@ module.exports = function templatePlugin(renderers) { result (in `x.type.js`) is a simple function with one argument that can be called to obtain a rendered template. */ - compilation.plugin('optimize-assets', (assets, done) => { + compilation.hooks.optimizeAssets.tapAsync(p, (assets, done) => { const renders = [] const chunksByName = compilation.chunks.reduce( diff --git a/library/webpack-plugins/watch-context-plugin.js b/library/webpack-plugins/watch-context-plugin.js index c897ab3d..028ff063 100644 --- a/library/webpack-plugins/watch-context-plugin.js +++ b/library/webpack-plugins/watch-context-plugin.js @@ -2,11 +2,13 @@ Simply adds the context as a context dependency */ +const p = 'watch-context-plugin' + module.exports = function watchContextPlugin() { return { apply: compiler => { - compiler.plugin('after-compile', (compilation, done) => { - compilation.contextDependencies.push(compiler.options.context) + compiler.hooks.afterCompile.tapAsync(p, (compilation, done) => { + compilation.contextDependencies.add(compiler.options.context) done() }) } diff --git a/library/webpack-plugins/websocket-communication-plugin.js b/library/webpack-plugins/websocket-communication-plugin.js index b1d02755..d2fe0f07 100644 --- a/library/webpack-plugins/websocket-communication-plugin.js +++ b/library/webpack-plugins/websocket-communication-plugin.js @@ -3,7 +3,7 @@ Plugins can get hold of the `send` method by adding the following hook: - compiler.plugin('websocket-send-available', send => { + compiler.hooks.websocketSendAvailable.tap('plugin-name', send => { ... }) @@ -12,16 +12,23 @@ message from `send`. */ +const { SyncHook } = require('tapable') const ConstDependency = require('webpack/lib/dependencies/ConstDependency') const NullFactory = require('webpack/lib/NullFactory') const ParserHelpers = require('webpack/lib/ParserHelpers') const net = require('net') const ws = require('ws') +const p = 'websocket-communication-plugin' + module.exports = function websocketCommunicationPlugin() { return { apply: compiler => { + // we should add this check to all hooks we create + if (compiler.hooks.websocketSendAvailable) throw new Error('Hook `websocketSendAvailable` already in use') + compiler.hooks.websocketSendAvailable = new SyncHook(['send']) + const freePort = findFreePort() const webSocketServer = freePort.then(startWebSocketServer) @@ -30,33 +37,36 @@ module.exports = function websocketCommunicationPlugin() { let port // provide the send function - compiler.plugin('environment', () => { - compiler.applyPlugins('websocket-send-available', send) + compiler.hooks.environment.tap(p, () => { + compiler.hooks.websocketSendAvailable.call(send) }) // wait for a free port before we start compiling - compiler.plugin('before-compile', (params, done) => { + compiler.hooks.beforeCompile.tapAsync(p, (params, done) => { freePort.then(found => { port = found }).then(_ => { done() }).catch(done) }) // make sure the __webpack_websocket_port__ is available in modules (code copied from ExtendedApiPlugin) - compiler.plugin('compilation', (compilation, { normalModuleFactory }) => { + compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { compilation.dependencyFactories.set(ConstDependency, new NullFactory()) compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.plugin('require-extensions', function(source, chunk, hash) { + compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { const buf = [ source, '', '// __webpack_websocket_port__', - `${this.requireFn}.wsp = ${port};` + `${compilation.mainTemplate.requireFn}.wsp = ${port};` ] - return this.asString(buf) - }) - compilation.mainTemplate.plugin('global-hash', () => true) - normalModuleFactory.plugin('parser', (parser, parserOptions) => { - parser.plugin(`expression __webpack_websocket_port__`, ParserHelpers.toConstantDependency('__webpack_require__.wsp')) - parser.plugin(`evaluate typeof __webpack_websocket_port__`, ParserHelpers.evaluateToString('string')) + return buf.join('\n') }) + compilation.mainTemplate.hooks.globalHash.tap(p, () => true) + normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) + normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) + + function addParserHooks(parser, parserOptions) { + parser.hooks.expression.for('__webpack_websocket_port__').tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.wsp')) + parser.hooks.evaluateTypeof.for('__webpack_websocket_port__').tap(p, ParserHelpers.evaluateToString('string')) + } }) } } diff --git a/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js b/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js index 3e486fe9..05f5e75b 100644 --- a/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js +++ b/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js @@ -1,16 +1,18 @@ +const p = 'absolute-path-resolver-plugin' + module.exports = absolutePathResolverPlugin function absolutePathResolverPlugin(path) { return { apply: resolver => { - resolver.plugin('resolve', (request, callback) => { + resolver.hooks.resolve.tapAsync(p, (request, resolveContext, callback) => { const innerRequest = request.request if (innerRequest && innerRequest.startsWith('/')) { const newRequest = Object.assign({}, request, { path: path, request: './' + innerRequest.slice(1) }) - resolver.doResolve('resolve', newRequest, 'looking for file in ' + path, callback, true) + resolver.doResolve(resolver.hooks.resolve, newRequest, 'looking for file in ' + path, resolveContext, callback, true) } else return callback() diff --git a/library/webpack-resolver-plugins/fragment-resolver-plugin.js b/library/webpack-resolver-plugins/fragment-resolver-plugin.js index 2c240d5e..0497580b 100644 --- a/library/webpack-resolver-plugins/fragment-resolver-plugin.js +++ b/library/webpack-resolver-plugins/fragment-resolver-plugin.js @@ -1,16 +1,18 @@ +const p = 'fragment-resolver-plugin' + module.exports = fragmentResolverPlugin function fragmentResolverPlugin() { return { apply: resolver => { - resolver.plugin('resolve', (request, callback) => { + resolver.hooks.resolve.tapAsync(p, (request, resolveContext, callback) => { const innerRequest = request.request const [file, fragment] = (innerRequest && innerRequest.split('#')) || [] if (file && fragment) { const newRequest = Object.assign({}, request, { request: file + '?fragment=' + fragment }) - resolver.doResolve('resolve', newRequest, 'resolving without fragment', callback, true) + resolver.doResolve(resolver.hooks.resolve, newRequest, 'resolving without fragment', resolveContext, callback, true) } else return callback() diff --git a/package.json b/package.json index d4c15c1d..2016ee93 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,7 @@ { "private": true, - "workspaces": ["example", "library"] + "workspaces": [ + "example", + "library" + ] } diff --git a/yarn.lock b/yarn.lock index 2e13179a..4b37a486 100644 --- a/yarn.lock +++ b/yarn.lock @@ -355,8 +355,8 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.2.tgz#e49ac1adb458835e95ca6487bc20f916b37aff23" "@types/node@^8.0.53", "@types/node@^8.9.4": - version "8.10.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.2.tgz#f1fb9c73414832c5b00ee954c4bbf68394e2e526" + version "8.10.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.3.tgz#ee34a5c732703cf45d2fadc163a299a6b2f456c2" abbrev@1: version "1.1.1" @@ -369,11 +369,11 @@ accepts@~1.3.4, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" -acorn-dynamic-import@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" dependencies: - acorn "^4.0.3" + acorn "^5.0.0" acorn-es7-plugin@^1.0.12: version "1.1.7" @@ -389,7 +389,7 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.0, acorn@^4.0.3: +acorn@^4.0.0: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -412,7 +412,7 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.0.0, ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: +ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -430,14 +430,6 @@ ajv@^6.1.0: json-schema-traverse "^0.3.0" uri-js "^3.0.2" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -488,7 +480,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -1431,7 +1423,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.0.5: +bluebird@^3.0.5, bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1454,7 +1446,7 @@ body-parser@1.18.2: raw-body "2.3.2" type-is "~1.6.15" -boolbase@~1.0.0: +boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -1590,6 +1582,10 @@ buffer-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" +buffer-from@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-0.1.2.tgz#15f4b9bcef012044df31142c14333caf6e0260d0" + buffer-from@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" @@ -1647,6 +1643,24 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -1693,10 +1707,6 @@ camelcase-keys@^2.0.0: camelcase "^2.0.0" map-obj "^1.0.0" -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - camelcase@^2.0.0, camelcase@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" @@ -1728,12 +1738,12 @@ caniuse-api@^2.0.0: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000823" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000823.tgz#e68e5f8c70783ef4059d2ea0de81f551651da6fc" + version "1.0.30000824" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000824.tgz#bba3ff425296e04caa37fe426259206a7056551b" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000775, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: - version "1.0.30000823" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000823.tgz#b79842a5b5a48eaa416b73f5a5d7a23f52d26014" + version "1.0.30000824" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000824.tgz#de3bc1ba0bff4937302f8cb2a8632a8cc1c07f9a" capture-stack-trace@^1.0.0: version "1.0.0" @@ -1765,13 +1775,6 @@ caw@^2.0.0: tunnel-agent "^0.6.0" url-to-options "^1.0.1" -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1848,6 +1851,14 @@ chokidar@^2.0.2: optionalDependencies: fsevents "^1.1.2" +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +chrome-trace-event@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-0.1.2.tgz#90f36885d5345a50621332f0717b595883d5d982" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1890,14 +1901,6 @@ cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - cliui@^3.0.3, cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -1932,6 +1935,12 @@ coa@~1.0.1: dependencies: q "^1.1.2" +coa@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.1.tgz#f3f8b0b15073e35d70263fb1042cb2c023db38af" + dependencies: + q "^1.1.2" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -2024,6 +2033,10 @@ commander@2.9.0: dependencies: graceful-readlink ">= 1.0.0" +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" @@ -2133,6 +2146,17 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" @@ -2197,7 +2221,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" dependencies: @@ -2263,6 +2287,10 @@ css-modules-loader-core@^1.1.0: postcss-modules-scope "1.1.0" postcss-modules-values "1.3.0" +css-select-base-adapter@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.0.tgz#0102b3d14630df86c3eb9fa9f5456270106cf990" + css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" @@ -2272,6 +2300,15 @@ css-select@~1.2.0: domutils "1.5.1" nth-check "~1.0.1" +css-select@~1.3.0-rc0: + version "1.3.0-rc0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.3.0-rc0.tgz#6f93196aaae737666ea1036a8cb14a8fcb7a9231" + dependencies: + boolbase "^1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "^1.0.1" + css-selector-tokenizer@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" @@ -2280,10 +2317,28 @@ css-selector-tokenizer@^0.7.0: fastparse "^1.1.1" regexpu-core "^1.0.0" +css-tree@1.0.0-alpha.27: + version "1.0.0-alpha.27" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.27.tgz#f211526909c7dc940843d83b9376ed98ddb8de47" + dependencies: + mdn-data "^1.0.0" + source-map "^0.5.3" + +css-tree@1.0.0-alpha25: + version "1.0.0-alpha25" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha25.tgz#1bbfabfbf6eeef4f01d9108ff2edd0be2fe35597" + dependencies: + mdn-data "^1.0.0" + source-map "^0.5.3" + css-unit-converter@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.1.tgz#d9b9281adcfd8ced935bdbaba83786897f64e996" +css-url-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/css-url-regex/-/css-url-regex-1.1.0.tgz#83834230cc9f74c457de59eebd1543feeb83b7ec" + css-what@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" @@ -2329,6 +2384,12 @@ cssnano@^3.10.0: postcss-value-parser "^3.2.3" postcss-zindex "^2.0.1" +csso@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-3.5.0.tgz#acdbba5719e2c87bc801eadc032764b2e4b9d4e7" + dependencies: + css-tree "1.0.0-alpha.27" + csso@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" @@ -2350,11 +2411,9 @@ cwebp-bin@^4.0.0: bin-wrapper "^3.0.1" logalot "^2.0.0" -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - dependencies: - es5-ext "^0.10.9" +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" damerau-levenshtein@^1.0.0: version "1.0.4" @@ -2398,7 +2457,7 @@ debug@^3.1.0: dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2756,7 +2815,7 @@ duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" -duplexify@^3.2.0, duplexify@^3.5.0, duplexify@^3.5.1, duplexify@^3.5.3, duplexify@^3.5.4: +duplexify@^3.2.0, duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.5.1, duplexify@^3.5.3, duplexify@^3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" dependencies: @@ -2857,14 +2916,13 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" +enhanced-resolve@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.0.0.tgz#e34a6eaa790f62fccd71d93959f56b2b432db10a" dependencies: graceful-fs "^4.1.2" memory-fs "^0.4.0" - object-assign "^4.0.1" - tapable "^0.2.7" + tapable "^1.0.0" ensure-posix-path@^1.0.0: version "1.0.2" @@ -2878,7 +2936,7 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -errno@^0.1.3: +errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: @@ -2890,7 +2948,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.7.0: +es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0: version "1.11.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" dependencies: @@ -2908,59 +2966,6 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.42" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d" - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.1" - next-tick "1" - -es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2969,28 +2974,19 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-config-standard-jsx@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz#009e53c4ddb1e9ee70b4650ffe63a7f39f8836e1" - -eslint-config-standard-react@^5.0.0: +eslint-config-standard-jsx@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-react/-/eslint-config-standard-react-5.0.0.tgz#64c7b8140172852be810a53d48ee87649ff178e3" + resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-5.0.0.tgz#4abfac554f38668e0078c664569e7b2384e5d2aa" + +eslint-config-standard-react@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard-react/-/eslint-config-standard-react-6.0.0.tgz#d366d6c3c092426fd3ae794a4ca0b3cb131f2964" dependencies: - eslint-config-standard-jsx "^4.0.0" + eslint-config-standard-jsx "^5.0.0" -eslint-config-standard@^10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz#c061e4d066f379dc17cd562c64e819b4dd454591" +eslint-config-standard@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz#87ee0d3c9d95382dc761958cbb23da9eea31e0ba" eslint-import-resolver-node@^0.3.1: version "0.3.2" @@ -3033,14 +3029,14 @@ eslint-plugin-jsx-a11y@^6.0.2: emoji-regex "^6.1.0" jsx-ast-utils "^2.0.0" -eslint-plugin-node@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.2.1.tgz#80df3253c4d7901045ec87fa660a284e32bdca29" +eslint-plugin-node@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz#bf19642298064379315d7a4b2a75937376fa05e4" dependencies: ignore "^3.3.6" minimatch "^3.0.4" resolve "^1.3.3" - semver "5.3.0" + semver "^5.4.1" eslint-plugin-promise@^3.6.0: version "3.7.0" @@ -3158,13 +3154,6 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -3217,6 +3206,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + executable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/executable/-/executable-1.1.0.tgz#877980e9112f3391066da37265de7ad8434ab4d9" @@ -3606,6 +3607,13 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + follow-redirects@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" @@ -3664,7 +3672,14 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" -fs-extra@^4.0.2, fs-extra@^4.0.3: +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" dependencies: @@ -3672,6 +3687,23 @@ fs-extra@^4.0.2, fs-extra@^4.0.3: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3700,7 +3732,7 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.1: +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3922,12 +3954,12 @@ gm@^1.23.0: debug "^3.1.0" google-auth-library@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.3.2.tgz#053d5cae7fb2b83367adad25bd0b8c80e2a38125" + version "1.4.0" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.4.0.tgz#27dae3b6aceadcc115a9910b4f1ed27b68b1eb0b" dependencies: axios "^0.18.0" gcp-metadata "^0.6.2" - gtoken "^2.1.1" + gtoken "^2.2.0" jws "^3.1.4" lodash.isstring "^4.0.1" lru-cache "^4.1.2" @@ -3952,15 +3984,15 @@ google-auto-auth@^0.9.0: request "^2.79.0" google-gax@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-0.16.0.tgz#42c87cffe087b75ca0d374954558dbddb016eb85" + version "0.16.1" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-0.16.1.tgz#30bf1284a1c384cd31a01163def4d671cec10c0f" dependencies: duplexify "^3.5.4" extend "^3.0.0" globby "^8.0.0" - google-auto-auth "^0.9.0" + google-auto-auth "^0.10.0" google-proto-files "^0.15.0" - grpc "~1.9.1" + grpc "^1.10.0" is-stream-ended "^0.1.0" lodash "^4.17.2" protobufjs "^6.8.0" @@ -4037,16 +4069,7 @@ grpc@^1.10.0, grpc@^1.9.1: node-pre-gyp "0.7.0" protobufjs "^5.0.0" -grpc@~1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.9.1.tgz#18d7cfce153ebf952559e62dadbc8bbb85da1eac" - dependencies: - lodash "^4.15.0" - nan "^2.0.0" - node-pre-gyp "^0.6.39" - protobufjs "^5.0.0" - -gtoken@^2.1.1: +gtoken@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-2.3.0.tgz#4e0ffc16432d7041a1b3dbc1d97aac17a5dc964a" dependencies: @@ -4140,10 +4163,6 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -4402,10 +4421,16 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" -iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@~0.4.13: +iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" +iconv-lite@^0.4.17, iconv-lite@~0.4.13: + version "0.4.21" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" + dependencies: + safer-buffer "^2.1.0" + icss-replace-symbols@1.1.0, icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" @@ -4418,6 +4443,10 @@ ienoopen@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b" +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + ignore@^3.3.3, ignore@^3.3.5, ignore@^3.3.6: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" @@ -4433,16 +4462,16 @@ image-size@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.2.tgz#8ee316d4298b028b965091b673d5f1537adee5b4" -image-webpack-loader@^3.4.2: - version "3.6.0" - resolved "https://registry.yarnpkg.com/image-webpack-loader/-/image-webpack-loader-3.6.0.tgz#3dcf652238ba39440cadd325aa602e7e0f2afe54" +image-webpack-loader@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/image-webpack-loader/-/image-webpack-loader-4.2.0.tgz#927966728027b4837f7715b52d44691838fba3bf" dependencies: imagemin "^5.2.2" imagemin-gifsicle "^5.1.0" - imagemin-mozjpeg "^6.0.0" + imagemin-mozjpeg "^7.0.0" imagemin-optipng "^5.2.1" imagemin-pngquant "^5.0.0" - imagemin-svgo "^5.2.1" + imagemin-svgo "^6.0.0" imagemin-webp "^4.0.0" loader-utils "^1.1.0" object-assign "^4.1.1" @@ -4455,13 +4484,13 @@ imagemin-gifsicle@^5.1.0: gifsicle "^3.0.0" is-gif "^1.0.0" -imagemin-mozjpeg@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/imagemin-mozjpeg/-/imagemin-mozjpeg-6.0.0.tgz#71a32a457aa1b26117a68eeef2d9b190c2e5091e" +imagemin-mozjpeg@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/imagemin-mozjpeg/-/imagemin-mozjpeg-7.0.0.tgz#d926477fc6ef5f3a768a4222f7b2d808d3eba568" dependencies: - exec-buffer "^3.0.0" + execa "^0.8.0" is-jpg "^1.0.0" - mozjpeg "^4.0.0" + mozjpeg "^5.0.0" imagemin-optipng@^5.2.1: version "5.2.1" @@ -4480,12 +4509,13 @@ imagemin-pngquant@^5.0.0: is-stream "^1.1.0" pngquant-bin "^4.0.0" -imagemin-svgo@^5.2.1: - version "5.2.4" - resolved "https://registry.yarnpkg.com/imagemin-svgo/-/imagemin-svgo-5.2.4.tgz#6cd5d342cae4bcd8b483594e5315695df02b9e9b" +imagemin-svgo@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/imagemin-svgo/-/imagemin-svgo-6.0.0.tgz#2dd8c82946be42a8e2cbcae3c5bf007bc2b8b9e8" dependencies: + buffer-from "^0.1.1" is-svg "^2.0.0" - svgo "^0.7.0" + svgo "^1.0.0" imagemin-webp@^4.0.0: version "4.1.0" @@ -4562,10 +4592,6 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" -interpret@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" - invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -4970,6 +4996,13 @@ js-yaml@^3.9.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@~3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" @@ -4993,7 +5026,7 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" -json-loader@^0.5.4, json-loader@^0.5.7: +json-loader@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" @@ -5112,10 +5145,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - lazy-req@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-1.1.0.tgz#bdaebead30f8d824039ce0ce149d4daa07ba1fac" @@ -5397,7 +5426,7 @@ long@~3: version "3.2.0" resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" -longest@^1.0.0, longest@^1.0.1: +longest@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -5437,7 +5466,7 @@ lru-cache@^3.2.0: dependencies: pseudomap "^1.0.1" -lru-cache@^4.0.1, lru-cache@^4.1.2: +lru-cache@^4.0.1, lru-cache@^4.1.1, lru-cache@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" dependencies: @@ -5485,6 +5514,10 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" +mdn-data@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.0.tgz#a7056319da95a2d0881267d7263075042eb061e2" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -5600,11 +5633,7 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" -mime@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - -mime@^2.2.0: +mime@^2.0.3, mime@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.2.tgz#6b4c109d88031d7b5c23635f5b923da336d79121" @@ -5642,6 +5671,21 @@ minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" @@ -5911,11 +5955,22 @@ modelo@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/modelo/-/modelo-4.2.3.tgz#b278588a4db87fc1e5107ae3a277c0876f38d894" -mozjpeg@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/mozjpeg/-/mozjpeg-4.1.1.tgz#859030b24f689a53db9b40f0160d89195b88fd50" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" dependencies: - bin-build "^2.0.0" + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +mozjpeg@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/mozjpeg/-/mozjpeg-5.0.0.tgz#b8671c4924568a363de003ff2fd397ab83f752c5" + dependencies: + bin-build "^2.2.0" bin-wrapper "^3.0.0" logalot "^2.0.0" @@ -5937,7 +5992,7 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.0.0, nan@^2.10.0, nan@^2.3.0: +nan@^2.10.0, nan@^2.3.0: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -5970,10 +6025,6 @@ neo-async@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f" -next-tick@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - nice-try@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" @@ -6107,9 +6158,9 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" -normalize.css@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf" +normalize.css@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.0.tgz#14ac5e461612538a4ce9be90a7da23f86e718493" npm-conf@^1.1.0: version "1.1.3" @@ -6133,7 +6184,7 @@ npmlog@^4.0.2: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@~1.0.1: +nth-check@^1.0.1, nth-check@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" dependencies: @@ -6190,6 +6241,13 @@ object.assign@^4.0.1: has-symbols "^1.0.0" object-keys "^1.0.11" +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -6203,6 +6261,15 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" +object.values@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.0.4.tgz#e524da09b4f66ff05df457546ec72ac99f13069a" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -6354,6 +6421,14 @@ pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + param-case@2.1.x: version "2.1.1" resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" @@ -6547,6 +6622,14 @@ postcss-apply@^0.8.0: balanced-match "^0.4.2" postcss "^6.0.0" +postcss-apply@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/postcss-apply/-/postcss-apply-0.9.0.tgz#a152e6e34a6c55d0895751929319c262c5d8c289" + dependencies: + babel-runtime "^6.23.0" + balanced-match "^0.4.2" + postcss "^6.0.0" + postcss-attribute-case-insensitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-2.0.0.tgz#94dc422c8f90997f16bd33a3654bbbec084963b4" @@ -7159,6 +7242,10 @@ progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + promise-polyfill@^7.1.0: version "7.1.2" resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b" @@ -7233,7 +7320,7 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" -pump@^2.0.0: +pump@^2.0.0, pump@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" dependencies: @@ -7394,16 +7481,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.32: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: @@ -7415,6 +7493,15 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +"readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -7698,13 +7785,7 @@ rgb@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/rgb/-/rgb-0.1.0.tgz#be27b291e8feffeac1bd99729721bfa40fc037b5" -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@2, rimraf@^2.2.6, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: +rimraf@2, rimraf@^2.2.6, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -7723,6 +7804,12 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + rx-lite-aggregates@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" @@ -7743,17 +7830,15 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -sax@~1.2.1: +safer-buffer@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.0.tgz#d9f653a55538c8d7829cb1a92e90bbcbc5ff5d3b" + +sax@~1.2.1, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -schema-utils@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" - dependencies: - ajv "^5.0.0" - -schema-utils@^0.4.5: +schema-utils@^0.4.2, schema-utils@^0.4.3, schema-utils@^0.4.5: version "0.4.5" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" dependencies: @@ -7776,14 +7861,10 @@ semver-truncate@^1.0.0: dependencies: semver "^5.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" -semver@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - semver@^4.0.3: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" @@ -7806,6 +7887,10 @@ send@0.16.2: range-parser "~1.2.0" statuses "~1.4.0" +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + serve-static@1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" @@ -7977,7 +8062,7 @@ source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" -source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: +source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -8050,6 +8135,16 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + dependencies: + safe-buffer "^5.1.1" + +stable@~0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.6.tgz#910f5d2aed7b520c6e777499c1f32e139fdecb10" + stat-mode@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502" @@ -8083,6 +8178,13 @@ stream-combiner2@^1.1.1: duplexer2 "~0.1.0" readable-stream "^2.0.2" +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + stream-events@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.3.tgz#73502d794e9e03607682e0c21948406cc650e54c" @@ -8238,12 +8340,6 @@ supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - supports-color@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" @@ -8262,6 +8358,25 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" +svgo@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.0.5.tgz#7040364c062a0538abacff4401cea6a26a7a389a" + dependencies: + coa "~2.0.1" + colors "~1.1.2" + css-select "~1.3.0-rc0" + css-select-base-adapter "~0.1.0" + css-tree "1.0.0-alpha25" + css-url-regex "^1.1.0" + csso "^3.5.0" + js-yaml "~3.10.0" + mkdirp "~0.5.1" + object.values "^1.0.4" + sax "~1.2.4" + stable "~0.1.6" + unquote "~1.1.1" + util.promisify "~1.0.0" + table@4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" @@ -8273,9 +8388,9 @@ table@4.0.2: slice-ansi "1.0.0" string-width "^2.1.1" -tapable@^0.2.7: - version "0.2.8" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" +tapable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" tar-pack@^3.4.0: version "3.4.1" @@ -8354,6 +8469,10 @@ through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +time-fix-plugin@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/time-fix-plugin/-/time-fix-plugin-2.0.0.tgz#d112f1e415b6ed269e008a42990ddbf8053fc315" + time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" @@ -8489,6 +8608,13 @@ ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + uglify-js@3.3.x: version "3.3.18" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.3.18.tgz#e16df66d71638df3c9bc61cce827e46f24bdac02" @@ -8496,35 +8622,23 @@ uglify-js@3.3.x: commander "~2.15.0" source-map "~0.6.1" -uglify-js@^2.8.29: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uglifyjs-webpack-plugin@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" +uglifyjs-webpack-plugin@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.4.tgz#5eec941b2e9b8538be0a20fc6eda25b14c7c1043" dependencies: - source-map "^0.5.6" - uglify-js "^2.8.29" - webpack-sources "^1.0.1" + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - unbzip2-stream@^1.0.9: version "1.2.5" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz#73a033a567bbbde59654b193c44d48a7e4f43c47" @@ -8555,6 +8669,18 @@ uniqs@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + unique-stream@^2.0.2: version "2.2.1" resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" @@ -8591,6 +8717,10 @@ unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -8620,13 +8750,13 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" -url-loader@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.6.2.tgz#a007a7109620e9d988d14bce677a1decb9a993f7" +url-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.0.1.tgz#61bc53f1f184d7343da2728a1289ef8722ea45ee" dependencies: - loader-utils "^1.0.2" - mime "^1.4.1" - schema-utils "^0.3.0" + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^0.4.3" url-parse-lax@^1.0.0: version "1.0.0" @@ -8661,6 +8791,13 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" +util.promisify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3, util@^0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -8795,7 +8932,7 @@ warning@^3.0.0: dependencies: loose-envify "^1.0.0" -watchpack@^1.4.0: +watchpack@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed" dependencies: @@ -8820,39 +8957,36 @@ webpack-node-externals@^1.6.0: version "1.7.2" resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" -webpack-sources@^1.0.1: +webpack-sources@^1.0.1, webpack-sources@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" dependencies: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^3.8.1: - version "3.11.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.11.0.tgz#77da451b1d7b4b117adaf41a1a93b5742f24d894" +webpack@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.5.0.tgz#1e6f71e148ead02be265ff2879c9cd6bb30b8848" dependencies: acorn "^5.0.0" - acorn-dynamic-import "^2.0.0" + acorn-dynamic-import "^3.0.0" ajv "^6.1.0" ajv-keywords "^3.1.0" - async "^2.1.2" - enhanced-resolve "^3.4.0" - escope "^3.6.0" - interpret "^1.0.0" - json-loader "^0.5.4" - json5 "^0.5.1" + chrome-trace-event "^0.1.1" + enhanced-resolve "^4.0.0" + eslint-scope "^3.7.1" loader-runner "^2.3.0" loader-utils "^1.1.0" memory-fs "~0.4.1" + micromatch "^3.1.8" mkdirp "~0.5.0" + neo-async "^2.5.0" node-libs-browser "^2.0.0" - source-map "^0.5.3" - supports-color "^4.2.1" - tapable "^0.2.7" - uglifyjs-webpack-plugin "^0.4.6" - watchpack "^1.4.0" + schema-utils "^0.4.2" + tapable "^1.0.0" + uglifyjs-webpack-plugin "^1.2.4" + watchpack "^1.5.0" webpack-sources "^1.0.1" - yargs "^8.0.2" websocket-driver@>=0.5.1: version "0.7.0" @@ -8889,22 +9023,20 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + dependencies: + errno "~0.1.7" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -8936,13 +9068,11 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" +ws@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.1.1.tgz#1d43704689711ac1942fd2f283e38f825c4b8b95" dependencies: async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" x-xss-protection@1.1.0: version "1.1.0" @@ -8968,6 +9098,10 @@ y18n@^3.2.0, y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -9008,15 +9142,6 @@ yargs@^8.0.2: y18n "^3.2.1" yargs-parser "^7.0.0" -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - yauzl@^2.2.1, yauzl@^2.4.2: version "2.9.1" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.9.1.tgz#a81981ea70a57946133883f029c5821a89359a7f" From b10da138c6b35bcfe0bb9b65720087a292a39e65 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Sun, 8 Apr 2018 13:59:27 +0200 Subject: [PATCH 02/16] moved web related options into `build.js` --- library/lib/build.js | 332 ++++++++++-------- .../webpack-plugins/react-universal-plugin.js | 67 +--- .../target-based-plugins-plugin.js | 22 -- 3 files changed, 201 insertions(+), 220 deletions(-) delete mode 100644 library/webpack-plugins/target-based-plugins-plugin.js diff --git a/library/lib/build.js b/library/lib/build.js index 369e1d67..a7824e81 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -4,6 +4,7 @@ process.on('unhandledRejection', (reason, p) => { console.log('Unhandled rejection of:\n', p, '\nReason:\n', reason) }) +const findYarnWorkspaceRoot = require('find-yarn-workspace-root') const fs = require('fs-extra') const nodeExternals = require('webpack-node-externals') const path = require('path') @@ -19,7 +20,6 @@ const makeAdditionalEntriesPlugin = require('../webpack-plugins/make-additional- const mergeCssPlugin = require('../webpack-plugins/merge-css-plugin') const reactUniversalPlugin = require('../webpack-plugins/react-universal-plugin') const sourceMapPlugin = require('../webpack-plugins/source-map-plugin') -const targetBasedPluginsPlugin = require('../webpack-plugins/target-based-plugins-plugin') const templatePlugin = require('../webpack-plugins/template-plugin') const watchContextPlugin = require('../webpack-plugins/watch-context-plugin') const websocketCommunicationPlugin = require('../webpack-plugins/websocket-communication-plugin') @@ -30,8 +30,8 @@ const fragmentResolverPlugin = require('../webpack-resolver-plugins/fragment-res const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin') const ExtendedAPIPlugin = require('webpack/lib/ExtendedAPIPlugin') const ProgressBarPlugin = require('progress-bar-webpack-plugin') -const findYarnWorkspaceRoot = require('find-yarn-workspace-root') const TimeFixPlugin = require('time-fix-plugin') // https://github.com/webpack/watchpack/issues/25 +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const isProduction = process.env.NODE_ENV === 'production' @@ -94,28 +94,33 @@ const imageSizeLoader = { options: { useImageMagick: true } } +const urlLoader = { + loader: 'url-loader', + options: { limit: 5000 } +} + module.exports = function build({ watch }) { const cwd = process.cwd() - const target = path.resolve(cwd, 'target') - fs.removeSync(target) - const srcDir = path.resolve(cwd, 'src') - const yarnWorkspaceDir = findYarnWorkspaceRoot(cwd) + const targetDir = path.resolve(cwd, 'target') + fs.removeSync(targetDir) - // This needs to be a function, if this would be an object things might breack - // because webpack stores state in the options object :-( - function getOptions() { + const mode = isProduction ? 'production' : 'development' + const outputPath = path.join(targetDir, publicPath) + + function nodeOptions() { return { - mode: isProduction ? 'production' : 'development', + mode, target: 'node', + context: srcDir, devtool: false, output: { filename: '[name]', chunkFilename: '[name]-[hash].js', - path: path.join(target, publicPath), + path: outputPath, publicPath, libraryTarget: 'commonjs2' }, @@ -123,144 +128,195 @@ module.exports = function build({ watch }) { nodeExternals(externalConfForModulesDir('node_modules')), yarnWorkspaceDir && nodeExternals(externalConfForModulesDir(path.resolve(yarnWorkspaceDir, 'node_modules'))) ].filter(Boolean), - resolve: { - extensions: ['.js'], - modules: ['node_modules'], - plugins: [absolutePathResolverPlugin(srcDir), fragmentResolverPlugin()] - }, - resolveLoader: { - modules: [ - path.resolve(__dirname, '../webpack-loaders'), - 'node_modules' - ].filter(Boolean) + optimization: { + minimize: false, + namedChunks: false, + splitChunks: false }, + resolve: resolveOptions(), + resolveLoader: resolveLoaderOptions(), + module: moduleOptions(), + plugins: [ + ...pluginsOptions().all(), + ...pluginsOptions().node() + ] + } + } + + function webOptions() { + return { + mode, + target: 'web', context: srcDir, + devtool: false, + entry: false, + output: { + filename: '[id].[hash].js', + chunkFilename: '[id].[hash].js', + path: outputPath, + publicPath + }, optimization: { namedChunks: false, - minimize: false, - splitChunks: false + runtimeChunk: 'single', + minimize: isProduction, + minimizer: [ + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap: true // this one is important + }) + ], + splitChunks: { + chunks: 'all', + minSize: 10000 + } }, + resolve: resolveOptions(), + resolveLoader: resolveLoaderOptions(), module: { - // noParse: https://webpack.js.org/configuration/module/#module-noparse - rules: [{ oneOf: [ - - { - type: 'json', - test: /\.json$/, - loaders: [] - }, - - { - test: /\.entry\.css$/, - loaders: ['to-json-file-loader', cssLoader] - }, - - { - test: /\.css$/, - loaders: ['json-loader', cssLoader], - exclude: /node_modules/ - }, - - { - test: /\.css$/, - loaders: ['json-loader', cssLoaderMinifyOnly] - }, - - { - test: /\.js$/, - resourceQuery: /transpiled-javascript-string/, - loaders: ['raw-loader', babelLoader] - }, - - { - resource: { - test: /(\.html\.js|\.js)$/, - or: [{ exclude: /node_modules/ }, kaliberBuildClientModules], - }, - loaders: [babelLoader] - }, + unsafeCache: false, + ...moduleOptions() + }, + plugins: [ + ...pluginsOptions().all(), + ...pluginsOptions().web() + ] + } + } - { - test: /\.js$/ - }, + function resolveOptions() { + return { + extensions: ['.js'], + modules: ['node_modules'], + plugins: [absolutePathResolverPlugin(srcDir), fragmentResolverPlugin()] + } + } - { - test: /\.svg$/, - resourceQuery: /fragment/, - loaders: ['fragment-loader'] - }, + function resolveLoaderOptions() { + return { + modules: [ + path.resolve(__dirname, '../webpack-loaders'), + 'node_modules' + ] + } + } - { - test: /\.svg$/, - loaders: [ - { - loader: 'url-loader', - options: { limit: 5000 } - }, - imageLoader - ] + function moduleOptions() { + return { + // noParse: https://webpack.js.org/configuration/module/#module-noparse + rules: [{ oneOf: [ + + { + type: 'json', + test: /\.json$/, + loaders: [] + }, + + { + test: /\.entry\.css$/, + loaders: ['to-json-file-loader', cssLoader] + }, + + { + test: /\.css$/, + loaders: ['json-loader', cssLoader], + exclude: /node_modules/ + }, + + { + test: /\.css$/, + loaders: ['json-loader', cssLoaderMinifyOnly] + }, + + { + test: /\.js$/, + resourceQuery: /transpiled-javascript-string/, + loaders: ['raw-loader', babelLoader] + }, + + { + resource: { + test: /(\.html\.js|\.js)$/, + or: [{ exclude: /node_modules/ }, kaliberBuildClientModules], }, + loaders: [babelLoader] + }, + + { + test: /\.js$/ + }, + + { + test: /\.svg$/, + resourceQuery: /fragment/, + loaders: ['fragment-loader'] + }, + + { + test: /\.svg$/, + loaders: [ + urlLoader, + imageLoader + ] + }, + + { + test: /\.(jpe?g|png|gif)$/, + loaders: [ + urlLoader, + isProduction && imageLoader, + imageSizeLoader + ].filter(Boolean) + }, - { - test: /\.(jpe?g|png|gif)$/, - loaders: [ - { - loader: 'url-loader', - options: { limit: 5000 } - }, - isProduction && imageLoader, - imageSizeLoader - ].filter(Boolean) - }, + { + loader: 'file-loader' + } - { - loader: 'file-loader' - } + ]}] + } + } - ]}] - }, - // server and compilation process plugins - plugins: [ - targetBasedPluginsPlugin({ - all: [ - new ProgressBarPlugin(), - watch && websocketCommunicationPlugin(), - makeAdditionalEntriesPlugin(), - new CaseSensitivePathsPlugin(), - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), - 'process.env.WATCH': watch - }), - new webpack.ProvidePlugin({ - React: 'react', - Component: ['react', 'Component'] - }), - sourceMapPlugin(), - ].filter(Boolean), - node: [ - new TimeFixPlugin(), - watch && new ExtendedAPIPlugin(), - configLoaderPlugin(), - watchContextPlugin(), - reactUniversalPlugin(), // claims .entry.js - templatePlugin(templateRenderers), // does work on .*.js - mergeCssPlugin(), - copyUnusedFilesPlugin(), - watch && hotCssReplacementPlugin() - ].filter(Boolean), - web: [ - chunkManifestPlugin(), - watch && hotModuleReplacementPlugin() - ].filter(Boolean) - }) - ], + function pluginsOptions() { + return { + all: () => [ + new ProgressBarPlugin(), + watch && websocketCommunicationPlugin(), + makeAdditionalEntriesPlugin(), + new CaseSensitivePathsPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), + 'process.env.WATCH': watch + }), + new webpack.ProvidePlugin({ + React: 'react', + Component: ['react', 'Component'] + }), + sourceMapPlugin(), + ].filter(Boolean), + node: () => [ + new TimeFixPlugin(), + watch && new ExtendedAPIPlugin(), + configLoaderPlugin(), + watchContextPlugin(), + reactUniversalPlugin(webOptions()), // claims .entry.js + templatePlugin(templateRenderers), // does work on .*.js + mergeCssPlugin(), + copyUnusedFilesPlugin(), + watch && hotCssReplacementPlugin() + ].filter(Boolean), + web: () => [ + chunkManifestPlugin(), + watch && hotModuleReplacementPlugin() + ].filter(Boolean) } + } - function externalConfForModulesDir (modulesDir) { - return { - whitelist: ['@kaliber/config', kaliberBuildClientModules, /\.css$/], - modulesDir - } + function externalConfForModulesDir (modulesDir) { + return { + whitelist: ['@kaliber/config', kaliberBuildClientModules, /\.css$/], + modulesDir } } @@ -269,10 +325,10 @@ module.exports = function build({ watch }) { else runOnce(compilationComplete) function createCompiler(entries) { - const options = getOptions() - options.entry = entries - - return webpack(options) + return webpack({ + entry: entries, + ...nodeOptions() + }) } function compilationComplete(err, stats) { diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index e1a36175..a7869536 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -8,8 +8,7 @@ const Stats = require('webpack/lib/Stats') const WebpackOptionsApply = require('webpack/lib/WebpackOptionsApply') const { ReplaceSource } = require('webpack-sources') const { relative } = require('path') -const UglifyJsPlugin = require('uglifyjs-webpack-plugin') - +const WebpackOptionsDefaulter = require('webpack/lib/WebpackOptionsDefaulter') /* The idea is simple: @@ -22,14 +21,14 @@ const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const p = 'react-universal-plugin' // works only when entry is an object -module.exports = function reactUniversalPlugin () { +module.exports = function reactUniversalPlugin (webCompilerOptions) { return { apply: compiler => { // keep a record of client entries for additional compiler runs (watch) const clientEntries = {} - const webCompiler = createWebCompiler(compiler, () => clientEntries) + const webCompiler = createWebCompiler(compiler, webCompilerOptions, () => clientEntries) // // when the webCompiler starts compiling add the recorded client entries webCompiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, createEntries, done) => { @@ -187,58 +186,7 @@ module.exports = function reactUniversalPlugin () { } } -function createWebCompiler(compiler, getEntries) { - - // TODO we need to use another mechanism so that we can set the options - // in the build.js and also we need to use the optiondefaulter from webpack - - // Massage the options to become a web configuration - const options = Object.assign({}, compiler.options) - options.name = 'react-universal-plugin-client-compiler' - options.target = 'web' - options.entry = undefined - options.externals = undefined - - options.output = Object.assign({}, options.output) - options.output.libraryTarget = 'var' - options.output.filename = '[id].[hash].js' - options.output.chunkFilename = '[id].[hash].js' - options.output.globalObject = 'window' - - options.optimization = Object.assign({}, options.optimization) - options.optimization.runtimeChunk = 'single' - options.optimization.minimize = options.mode === 'production' - options.optimization.minimizer = [ - new UglifyJsPlugin({ - cache: true, - parallel: true, - sourceMap: true // this one is important - }) - ] - options.optimization.splitChunks = { - chunks: 'all', - minSize: 10000, - minChunks: 1, - maxAsyncRequests: 5, - automaticNameDelimiter: '~', - maxInitialRequests: 3, - name: true, - filename: '[id].[hash].js', - cacheGroups: { - default: { - reuseExistingChunk: true, - minChunks: 2, - priority: -20 - } - } - } - - options.resolve = Object.assign({}, options.resolve) - options.resolve.aliasFields = ['browser'] - options.resolve.mainFields = ['browser', 'module', 'main'] - - options.module = Object.assign({}, options.module) - options.module.unsafeCache = false +function createWebCompiler(compiler, options, getEntries) { const webCompiler = createCompiler(compiler, options) @@ -272,10 +220,10 @@ function createWebCompiler(compiler, getEntries) { } function createCompiler(compiler, options) { - const childCompiler = new Compiler(options.context) - /* from lib/webpack.js */ - childCompiler.context = options.context + options = new WebpackOptionsDefaulter().process(options) + + const childCompiler = new Compiler(options.context) childCompiler.options = options // instead of using the NodeEnvironmentPlugin @@ -286,7 +234,6 @@ function createCompiler(compiler, options) { options.plugins.forEach(plugin => { plugin.apply(childCompiler) }) childCompiler.hooks.environment.call() childCompiler.hooks.afterEnvironment.call() - childCompiler.options = new WebpackOptionsApply().process(options, childCompiler) return childCompiler diff --git a/library/webpack-plugins/target-based-plugins-plugin.js b/library/webpack-plugins/target-based-plugins-plugin.js deleted file mode 100644 index e15a395f..00000000 --- a/library/webpack-plugins/target-based-plugins-plugin.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - Add plugins based on the target, plugins argument example: - - { - all: [ ... ], - node: [ ... ], - web: [ ... ] - } -*/ - -module.exports = function targetBasedPluginsPlugin(plugins) { - - return { - apply: compiler => { - plugins.all.forEach(applyPlugin) - const targetPlugins = plugins[compiler.options.target] - if (targetPlugins) targetPlugins.forEach(applyPlugin) - - function applyPlugin(plugin) { plugin.apply(compiler) } - } - } -} From 3810e9edc2cad6112e21744024415a5aebb528aa Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Sun, 8 Apr 2018 22:21:41 +0200 Subject: [PATCH 03/16] simplified hook related code --- .../webpack-plugins/config-loader-plugin.js | 4 +-- .../copy-unused-files-plugin.js | 4 +-- .../make-additional-entries-plugin.js | 16 +++-------- .../webpack-plugins/react-universal-plugin.js | 28 +++++++++---------- library/webpack-plugins/template-plugin.js | 8 +++--- .../webpack-plugins/watch-context-plugin.js | 3 +- .../websocket-communication-plugin.js | 4 +-- .../absolute-path-resolver-plugin.js | 2 +- .../fragment-resolver-plugin.js | 2 +- 9 files changed, 30 insertions(+), 41 deletions(-) diff --git a/library/webpack-plugins/config-loader-plugin.js b/library/webpack-plugins/config-loader-plugin.js index 6146dcce..b118816f 100644 --- a/library/webpack-plugins/config-loader-plugin.js +++ b/library/webpack-plugins/config-loader-plugin.js @@ -8,13 +8,13 @@ module.exports = function configLoaderPlugin() { apply: compiler => { compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { + normalModuleFactory.hooks.afterResolve.tap(p, data => { const { loaders, rawRequest } = data if (rawRequest === '@kaliber/config') loaders.push({ loader: require.resolve('../webpack-loaders/config-loader') }) - done(null, data) + return data }) }) } diff --git a/library/webpack-plugins/copy-unused-files-plugin.js b/library/webpack-plugins/copy-unused-files-plugin.js index 69144116..6a963400 100644 --- a/library/webpack-plugins/copy-unused-files-plugin.js +++ b/library/webpack-plugins/copy-unused-files-plugin.js @@ -12,7 +12,7 @@ module.exports = function copyUnusedFilesPlugin() { return { apply: compiler => { - compiler.hooks.afterEmit.tapAsync(p, (compilation, done) => { + compiler.hooks.afterEmit.tapPromise(p, compilation => { const context = compiler.context @@ -48,7 +48,7 @@ module.exports = function copyUnusedFilesPlugin() { }) ) - filesCopied.then(_ => { done() }).catch(done) + return filesCopied }) } } diff --git a/library/webpack-plugins/make-additional-entries-plugin.js b/library/webpack-plugins/make-additional-entries-plugin.js index 3f23e0f3..c928b169 100644 --- a/library/webpack-plugins/make-additional-entries-plugin.js +++ b/library/webpack-plugins/make-additional-entries-plugin.js @@ -39,7 +39,7 @@ module.exports = function makeAdditionalEntries() { apply: compiler => { compiler.hooks.claimEntries = new SyncWaterfallHook(['entries']) - compiler.hooks.makeAdditionalEntries = new AsyncSeriesHook(['compilation', 'createEntries']) + compiler.hooks.makeAdditionalEntries = new AsyncSeriesHook(['compilation', 'addEntries']) const entriesToMake = {} @@ -65,21 +65,13 @@ module.exports = function makeAdditionalEntries() { Note that plugins can depend on entries created in plugins registered before them. */ - compiler.hooks.make.tapAsync(p, (compilation, done) => { + compiler.hooks.make.tapPromise(p, compilation => { - addEntries(entriesToMake) + return addEntries(entriesToMake) .then(makeAdditionalEntries) - .then(_ => { done() }) - .catch(e => { done(e) }) function makeAdditionalEntries() { - return new Promise((resolve, reject) => { - compiler.hooks.makeAdditionalEntries.callAsync( - compilation, - (entries, done) => { addEntries(entries || {}).then(_ => { done() }).catch(done) }, - err => { err ? reject(err) : resolve() } - ) - }) + return compiler.hooks.makeAdditionalEntries.promise(compilation, addEntries) } function addEntries(entries) { diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index a7869536..1a70dc87 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -31,8 +31,8 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { const webCompiler = createWebCompiler(compiler, webCompilerOptions, () => clientEntries) // // when the webCompiler starts compiling add the recorded client entries - webCompiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, createEntries, done) => { - createEntries(clientEntries, done) + webCompiler.hooks.makeAdditionalEntries.tapPromise(p, (compilation, addEntries) => { + return addEntries(clientEntries) }) // check the parent compiler before creating a module, it might have already @@ -66,10 +66,9 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { }) // before we compile, make sure the timestamps (important for caching and changed by watch) are updated - compiler.hooks.beforeCompile.tapAsync(p, (params, done) => { + compiler.hooks.beforeCompile.tap(p, params => { webCompiler.fileTimestamps = compiler.fileTimestamps webCompiler.contextTimestamps = compiler.contextTimestamps - done() }) // we claim entries ending with `entry.js` and record them as client entries for the web compiler @@ -99,15 +98,15 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { */ compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.hooks.beforeResolve.tapAsync(p, (data, done) => { - if (!data) return done(null, data) + normalModuleFactory.hooks.beforeResolve.tap(p, data => { + if (!data) return data - if (data.dependencies.some(x => x instanceof ImportDependency)) return done() + if (data.dependencies.some(x => x instanceof ImportDependency)) return - done(null, data) + return data }) - normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { + normalModuleFactory.hooks.afterResolve.tap(p, data => { const { loaders, resourceResolveData: { query, path } } = data if (query === '?universal') { @@ -117,12 +116,13 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { if (!clientEntries[name]) clientEntries[name] = './' + name + '?universal-client' } - done(null, data) + return data }) }) // tell the web compiler to compile, emit the assets and notify the appropriate plugins - compiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, createEntries, done) => { + // Note, we can not use `make` because it's parralel + compiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, _, done) => { const startTime = Date.now() webCompiler.compile((err, webCompilation) => { @@ -196,16 +196,16 @@ function createWebCompiler(compiler, options, getEntries) { provide a friendly error if @kaliber/config is loaded from a client module */ webCompiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { + normalModuleFactory.hooks.afterResolve.tap(p, data => { const { loaders, rawRequest, resourceResolveData: { query } } = data if (query === '?universal-client') loaders.push({ loader: require.resolve('../webpack-loaders/react-universal-client-loader') }) if (rawRequest === '@kaliber/config') - return done('@kaliber/config\n------\nYou can not load @kaliber/config from a client module.\n\nIf you have a use-case, please open an issue so we can discuss how we can\nimplement this safely.\n------') + throw new Error('@kaliber/config\n------\nYou can not load @kaliber/config from a client module.\n\nIf you have a use-case, please open an issue so we can discuss how we can\nimplement this safely.\n------') - done(null, data) + return data }) }) diff --git a/library/webpack-plugins/template-plugin.js b/library/webpack-plugins/template-plugin.js index bfe18639..a5020039 100644 --- a/library/webpack-plugins/template-plugin.js +++ b/library/webpack-plugins/template-plugin.js @@ -52,7 +52,7 @@ module.exports = function templatePlugin(renderers) { as it would cause infinite loops */ compiler.hooks.normalModuleFactory.tap(p, normalModuleFactory => { - normalModuleFactory.hooks.afterResolve.tapAsync(p, (data, done) => { + normalModuleFactory.hooks.afterResolve.tap(p, data => { const { loaders, resourceResolveData: { query, path } } = data const renderInfo = getRenderInfo(path) @@ -62,7 +62,7 @@ module.exports = function templatePlugin(renderers) { loaders.push({ loader: templateLoader, options: { renderer } }) } - done(null, data) + return data }) }) @@ -81,7 +81,7 @@ module.exports = function templatePlugin(renderers) { result (in `x.type.js`) is a simple function with one argument that can be called to obtain a rendered template. */ - compilation.hooks.optimizeAssets.tapAsync(p, (assets, done) => { + compilation.hooks.optimizeAssets.tapPromise(p, assets => { const renders = [] const chunksByName = compilation.chunks.reduce( @@ -121,7 +121,7 @@ module.exports = function templatePlugin(renderers) { ) } - Promise.all(renders).then(_ => { done() }).catch(done) + return Promise.all(renders) }) }) } diff --git a/library/webpack-plugins/watch-context-plugin.js b/library/webpack-plugins/watch-context-plugin.js index 028ff063..41bbb961 100644 --- a/library/webpack-plugins/watch-context-plugin.js +++ b/library/webpack-plugins/watch-context-plugin.js @@ -7,9 +7,8 @@ const p = 'watch-context-plugin' module.exports = function watchContextPlugin() { return { apply: compiler => { - compiler.hooks.afterCompile.tapAsync(p, (compilation, done) => { + compiler.hooks.afterCompile.tap(p, compilation => { compilation.contextDependencies.add(compiler.options.context) - done() }) } } diff --git a/library/webpack-plugins/websocket-communication-plugin.js b/library/webpack-plugins/websocket-communication-plugin.js index d2fe0f07..2bde1281 100644 --- a/library/webpack-plugins/websocket-communication-plugin.js +++ b/library/webpack-plugins/websocket-communication-plugin.js @@ -42,9 +42,7 @@ module.exports = function websocketCommunicationPlugin() { }) // wait for a free port before we start compiling - compiler.hooks.beforeCompile.tapAsync(p, (params, done) => { - freePort.then(found => { port = found }).then(_ => { done() }).catch(done) - }) + compiler.hooks.beforeCompile.tapPromise(p, params => freePort.then(found => { port = found })) // make sure the __webpack_websocket_port__ is available in modules (code copied from ExtendedApiPlugin) compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { diff --git a/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js b/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js index 05f5e75b..12847f45 100644 --- a/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js +++ b/library/webpack-resolver-plugins/absolute-path-resolver-plugin.js @@ -12,7 +12,7 @@ function absolutePathResolverPlugin(path) { path: path, request: './' + innerRequest.slice(1) }) - resolver.doResolve(resolver.hooks.resolve, newRequest, 'looking for file in ' + path, resolveContext, callback, true) + resolver.doResolve(resolver.hooks.resolve, newRequest, 'looking for file in ' + path, resolveContext, callback) } else return callback() diff --git a/library/webpack-resolver-plugins/fragment-resolver-plugin.js b/library/webpack-resolver-plugins/fragment-resolver-plugin.js index 0497580b..51ae96d3 100644 --- a/library/webpack-resolver-plugins/fragment-resolver-plugin.js +++ b/library/webpack-resolver-plugins/fragment-resolver-plugin.js @@ -12,7 +12,7 @@ function fragmentResolverPlugin() { const newRequest = Object.assign({}, request, { request: file + '?fragment=' + fragment }) - resolver.doResolve(resolver.hooks.resolve, newRequest, 'resolving without fragment', resolveContext, callback, true) + resolver.doResolve(resolver.hooks.resolve, newRequest, 'resolving without fragment', resolveContext, callback) } else return callback() From e47486175fe0edf8d56b182b0df9c11c5bc4b206 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Mon, 9 Apr 2018 14:41:53 +0200 Subject: [PATCH 04/16] added breaking change to readme --- library/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/library/README.md b/library/README.md index 8f4f944d..a4eb4fab 100644 --- a/library/README.md +++ b/library/README.md @@ -2,6 +2,7 @@ Breaking changes: +- v0.0.?? - `chunk-manifest.json` changed - v0.0.47 - Universal apps no longer have an extra `
` around the root-app-node and the script-tag. - v0.0.44 - `*.entry.css` are now also hashed, use `css-manifest.json` to obtain the names - v0.0.41 - `*.*.js` are no longer all treated as templates, by default only `.html.js`, `.txt.js` and `.json.js` are considered From cdc4bdc91a9a86319a10a6510a70120d80175a20 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Mon, 9 Apr 2018 14:44:34 +0200 Subject: [PATCH 05/16] removed double comment --- library/webpack-plugins/react-universal-plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index 1a70dc87..cb337181 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -30,7 +30,7 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { const webCompiler = createWebCompiler(compiler, webCompilerOptions, () => clientEntries) - // // when the webCompiler starts compiling add the recorded client entries + // when the webCompiler starts compiling add the recorded client entries webCompiler.hooks.makeAdditionalEntries.tapPromise(p, (compilation, addEntries) => { return addEntries(clientEntries) }) From 5dd0de6ae7c7564a1f910e2b120b8a7b30376766 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Mon, 9 Apr 2018 14:54:24 +0200 Subject: [PATCH 06/16] added checks to hook registration --- library/webpack-plugins/chunk-manifest-plugin.js | 1 + library/webpack-plugins/hot-module-replacement-plugin.js | 2 +- library/webpack-plugins/make-additional-entries-plugin.js | 4 +++- library/webpack-plugins/merge-css-plugin.js | 1 + library/webpack-plugins/react-universal-plugin.js | 2 +- library/webpack-plugins/source-map-plugin.js | 2 +- library/webpack-plugins/websocket-communication-plugin.js | 1 - 7 files changed, 8 insertions(+), 5 deletions(-) diff --git a/library/webpack-plugins/chunk-manifest-plugin.js b/library/webpack-plugins/chunk-manifest-plugin.js index c5b79447..af1c4a94 100644 --- a/library/webpack-plugins/chunk-manifest-plugin.js +++ b/library/webpack-plugins/chunk-manifest-plugin.js @@ -25,6 +25,7 @@ module.exports = function chunkManifestPlugin() { apply: compiler => { compiler.hooks.compilation.tap(p, compilation => { + if (compilation.hooks.chunkManifest) throw new Error('Hook `chunkManifest` already in use') compilation.hooks.chunkManifest = new SyncHook(['chunkAssets']) const chunkAssets = {} diff --git a/library/webpack-plugins/hot-module-replacement-plugin.js b/library/webpack-plugins/hot-module-replacement-plugin.js index b01b5a13..44f2e919 100644 --- a/library/webpack-plugins/hot-module-replacement-plugin.js +++ b/library/webpack-plugins/hot-module-replacement-plugin.js @@ -4,8 +4,8 @@ The only thing we do is send a message when compilation completes. */ -const webpack = require('webpack') const ansiRegex = require('ansi-regex') +const webpack = require('webpack') const p = 'hot-module-replacement-plugin' diff --git a/library/webpack-plugins/make-additional-entries-plugin.js b/library/webpack-plugins/make-additional-entries-plugin.js index c928b169..10b1ca87 100644 --- a/library/webpack-plugins/make-additional-entries-plugin.js +++ b/library/webpack-plugins/make-additional-entries-plugin.js @@ -28,8 +28,8 @@ }) */ -const { AsyncSeriesHook, SyncWaterfallHook } = require('tapable') const SingleEntryDependency = require('webpack/lib/dependencies/SingleEntryDependency') +const { AsyncSeriesHook, SyncWaterfallHook } = require('tapable') const { createDependency } = require('webpack/lib/SingleEntryPlugin') const p = 'make-additional-entries' @@ -38,7 +38,9 @@ module.exports = function makeAdditionalEntries() { return { apply: compiler => { + if (compiler.hooks.claimEntries) throw new Error('Hook `claimEntries` already in use') compiler.hooks.claimEntries = new SyncWaterfallHook(['entries']) + if (compiler.hooks.makeAdditionalEntries) throw new Error('Hook `makeAdditionalEntries` already in use') compiler.hooks.makeAdditionalEntries = new AsyncSeriesHook(['compilation', 'addEntries']) const entriesToMake = {} diff --git a/library/webpack-plugins/merge-css-plugin.js b/library/webpack-plugins/merge-css-plugin.js index b93c1494..cbf8fe51 100644 --- a/library/webpack-plugins/merge-css-plugin.js +++ b/library/webpack-plugins/merge-css-plugin.js @@ -27,6 +27,7 @@ module.exports = function mergeCssPlugin() { apply: compiler => { compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { + if (compilation.hooks.chunkCssHashes) throw new Error('Hook `chunkCssHashes` already in use') compilation.hooks.chunkCssHashes = new SyncHook(['chunkName', 'cssHashes']) const newChunksWithCssAssets = {} diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index cb337181..62a9c21a 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -6,9 +6,9 @@ const ParserHelpers = require('webpack/lib/ParserHelpers') const RawModule = require('webpack/lib/RawModule') const Stats = require('webpack/lib/Stats') const WebpackOptionsApply = require('webpack/lib/WebpackOptionsApply') +const WebpackOptionsDefaulter = require('webpack/lib/WebpackOptionsDefaulter') const { ReplaceSource } = require('webpack-sources') const { relative } = require('path') -const WebpackOptionsDefaulter = require('webpack/lib/WebpackOptionsDefaulter') /* The idea is simple: diff --git a/library/webpack-plugins/source-map-plugin.js b/library/webpack-plugins/source-map-plugin.js index 0c73d0b5..c9d39898 100644 --- a/library/webpack-plugins/source-map-plugin.js +++ b/library/webpack-plugins/source-map-plugin.js @@ -3,8 +3,8 @@ has a source map available. */ -const { RawSource, ConcatSource } = require('webpack-sources') const path = require('path') +const { RawSource, ConcatSource } = require('webpack-sources') const p = 'source-map-plugin' diff --git a/library/webpack-plugins/websocket-communication-plugin.js b/library/webpack-plugins/websocket-communication-plugin.js index 2bde1281..d58965b9 100644 --- a/library/webpack-plugins/websocket-communication-plugin.js +++ b/library/webpack-plugins/websocket-communication-plugin.js @@ -25,7 +25,6 @@ module.exports = function websocketCommunicationPlugin() { return { apply: compiler => { - // we should add this check to all hooks we create if (compiler.hooks.websocketSendAvailable) throw new Error('Hook `websocketSendAvailable` already in use') compiler.hooks.websocketSendAvailable = new SyncHook(['send']) From 6b17ee90da9217e65e7544edad38bd96f6d724f9 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Mon, 9 Apr 2018 15:12:16 +0200 Subject: [PATCH 07/16] updated versions in `package.json` files to reflect `yarn.lock` --- example/package.json | 12 +++++----- library/package.json | 52 ++++++++++++++++++++-------------------- yarn.lock | 56 ++++++++++++++++++++++---------------------- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/example/package.json b/example/package.json index 3a0948e3..f6051ea9 100644 --- a/example/package.json +++ b/example/package.json @@ -13,13 +13,13 @@ "@kaliber/build": "*" }, "dependencies": { - "express-basic-auth": "^1.1.3", - "firebase": "^4.6.2", - "firebase-admin": "^5.5.1", + "express-basic-auth": "^1.1.4", + "firebase": "^4.12.1", + "firebase-admin": "^5.12.0", "mjml": "^4.0.3", "normalize.css": "^8.0.0", - "react": "^16.2.0", - "react-dom": "^16.2.0", + "react": "^16.3.1", + "react-dom": "^16.3.1", "xml": "^1.0.1" } -} +} \ No newline at end of file diff --git a/library/package.json b/library/package.json index d2970327..f4a806e5 100644 --- a/library/package.json +++ b/library/package.json @@ -16,60 +16,60 @@ "@kaliber/config": "^0.0.1", "ansi-regex": "^3.0.0", "babel-core": "^6.26.0", - "babel-eslint": "^8.0.2", - "babel-loader": "^7.1.2", + "babel-eslint": "^8.2.2", + "babel-loader": "^7.1.4", "babel-plugin-add-module-exports": "^0.2.1", "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-transform-async-to-generator": "^6.24.1", - "babel-plugin-transform-class-properties": "^6.23.0", + "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", - "caniuse-lite": "^1.0.30000775", - "case-sensitive-paths-webpack-plugin": "^2.1.1", - "compression": "^1.7.1", + "caniuse-lite": "^1.0.30000824", + "case-sensitive-paths-webpack-plugin": "^2.1.2", + "compression": "^1.7.2", "cross-spawn": "^6.0.5", "cssnano": "^3.10.0", - "eslint": "^4.12.1", + "eslint": "^4.19.1", "eslint-config-standard": "^11.0.0", "eslint-config-standard-react": "^6.0.0", - "eslint-plugin-import": "^2.8.0", - "eslint-plugin-jsx-a11y": "^6.0.2", + "eslint-plugin-import": "^2.10.0", + "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-node": "^6.0.1", - "eslint-plugin-promise": "^3.6.0", - "eslint-plugin-react": "^7.5.1", + "eslint-plugin-promise": "^3.7.0", + "eslint-plugin-react": "^7.7.0", "eslint-plugin-standard": "^3.0.1", - "express": "^4.16.2", - "file-loader": "^1.1.5", - "find-yarn-workspace-root": "^1.0.0", + "express": "^4.16.3", + "file-loader": "^1.1.11", + "find-yarn-workspace-root": "^1.1.0", "fs-extra": "^5.0.0", - "gm": "^1.23.0", - "helmet": "^3.9.0", + "gm": "^1.23.1", + "helmet": "^3.12.0", "history": "^4.7.2", - "hoist-non-react-statics": "^2.3.1", + "hoist-non-react-statics": "^2.5.0", "image-maxsize-webpack-loader": "^1.0.0", "image-webpack-loader": "^4.2.0", "json-loader": "^0.5.7", "loader-utils": "^1.1.0", - "postcss": "^6.0.14", + "postcss": "^6.0.21", "postcss-apply": "^0.9.0", - "postcss-cssnext": "^3.0.2", - "postcss-import": "^11.0.0", + "postcss-cssnext": "^3.1.0", + "postcss-import": "^11.1.0", "postcss-modules": "^1.1.0", - "progress-bar-webpack-plugin": "^1.10.0", + "progress-bar-webpack-plugin": "^1.11.0", "raw-loader": "^0.5.1", - "react": "^16.2.0", - "react-dom": "^16.2.0", + "react": "^16.3.1", + "react-dom": "^16.3.1", "source-map": "^0.6.1", "tapable": "^1.0.0", "time-fix-plugin": "^2.0.0", "uglifyjs-webpack-plugin": "^1.2.4", "url-loader": "^1.0.1", - "walk-sync": "^0.3.1", + "walk-sync": "^0.3.2", "webpack": "^4.5.0", - "webpack-node-externals": "^1.6.0", + "webpack-node-externals": "^1.7.2", "ws": "^5.1.1" }, "keywords": [ @@ -87,4 +87,4 @@ "bugs": { "url": "https://github.com/kaliberjs/build/issues" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4b37a486..10ca3a2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -731,7 +731,7 @@ babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" -babel-eslint@^8.0.2: +babel-eslint@^8.2.2: version "8.2.2" resolved "http://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.2.tgz#1102273354c6f0b29b4ea28a65f97d122296b68b" dependencies: @@ -864,7 +864,7 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-loader@^7.1.2: +babel-loader@^7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.4.tgz#e3463938bd4e6d55d1c174c5485d406a188ed015" dependencies: @@ -932,7 +932,7 @@ babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async- babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-properties@^6.23.0: +babel-plugin-transform-class-properties@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" dependencies: @@ -1741,7 +1741,7 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000824" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000824.tgz#bba3ff425296e04caa37fe426259206a7056551b" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000775, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000824: version "1.0.30000824" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000824.tgz#de3bc1ba0bff4937302f8cb2a8632a8cc1c07f9a" @@ -1749,7 +1749,7 @@ capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" -case-sensitive-paths-webpack-plugin@^2.1.1: +case-sensitive-paths-webpack-plugin@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.1.2.tgz#c899b52175763689224571dad778742e133f0192" @@ -2057,7 +2057,7 @@ compressible@^2.0.12, compressible@~2.0.13: dependencies: mime-db ">= 1.33.0 < 2" -compression@^1.7.1: +compression@^1.7.2: version "1.7.2" resolved "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz#aaffbcd6aaf854b44ebb280353d5ad1651f59a69" dependencies: @@ -3002,7 +3002,7 @@ eslint-module-utils@^2.2.0: debug "^2.6.8" pkg-dir "^1.0.0" -eslint-plugin-import@^2.8.0: +eslint-plugin-import@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.10.0.tgz#fa09083d5a75288df9c6c7d09fe12255985655e7" dependencies: @@ -3017,7 +3017,7 @@ eslint-plugin-import@^2.8.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" -eslint-plugin-jsx-a11y@^6.0.2: +eslint-plugin-jsx-a11y@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz#54583d1ae442483162e040e13cc31865465100e5" dependencies: @@ -3038,11 +3038,11 @@ eslint-plugin-node@^6.0.1: resolve "^1.3.3" semver "^5.4.1" -eslint-plugin-promise@^3.6.0: +eslint-plugin-promise@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz#f4bde5c2c77cdd69557a8f69a24d1ad3cfc9e67e" -eslint-plugin-react@^7.5.1: +eslint-plugin-react@^7.7.0: version "7.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz#f606c719dbd8a1a2b3d25c16299813878cca0160" dependencies: @@ -3066,7 +3066,7 @@ eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^4.12.1: +eslint@^4.19.1: version "4.19.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" dependencies: @@ -3252,13 +3252,13 @@ expect-ct@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.1.0.tgz#52735678de18530890d8d7b95f0ac63640958094" -express-basic-auth@^1.1.3: +express-basic-auth@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/express-basic-auth/-/express-basic-auth-1.1.4.tgz#8d44ca5d98faaaa125ed5aa847384aef674616a6" dependencies: basic-auth "^1.1.0" -express@^4.16.2: +express@^4.16.3: version "4.16.3" resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" dependencies: @@ -3442,7 +3442,7 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -file-loader@^1.1.5: +file-loader@^1.1.11: version "1.1.11" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.11.tgz#6fe886449b0f2a936e43cabaac0cdbfb369506f8" dependencies: @@ -3554,14 +3554,14 @@ find-versions@^1.0.0: meow "^3.5.0" semver-regex "^1.0.0" -find-yarn-workspace-root@^1.0.0: +find-yarn-workspace-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.1.0.tgz#9817b6748cb90719f4dc37b4538bb200c697356f" dependencies: fs-extra "^4.0.3" micromatch "^3.1.4" -firebase-admin@^5.5.1: +firebase-admin@^5.12.0: version "5.12.0" resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-5.12.0.tgz#3291b0466b4d161cb4135e83c97f9878e7768cac" dependencies: @@ -3575,7 +3575,7 @@ firebase-admin@^5.5.1: jsonwebtoken "8.1.0" node-forge "0.7.4" -firebase@^4.6.2: +firebase@^4.12.1: version "4.12.1" resolved "https://registry.yarnpkg.com/firebase/-/firebase-4.12.1.tgz#973776a6d74d5314a20d8413fe333412082fc919" dependencies: @@ -3944,7 +3944,7 @@ glogg@^1.0.0: dependencies: sparkles "^1.0.0" -gm@^1.23.0: +gm@^1.23.1: version "1.23.1" resolved "https://registry.yarnpkg.com/gm/-/gm-1.23.1.tgz#2edeeb958084d0f8ea7988e5d995b1c7dfc14777" dependencies: @@ -4282,7 +4282,7 @@ helmet-csp@2.7.0: lodash.reduce "4.6.0" platform "1.3.5" -helmet@^3.9.0: +helmet@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.12.0.tgz#2098e35cf4e51c64c2f1d38670b7d382a377d92c" dependencies: @@ -4329,7 +4329,7 @@ hoek@4.x.x: version "4.2.1" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" -hoist-non-react-statics@^2.3.1: +hoist-non-react-statics@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz#d2ca2dfc19c5a91c5a6615ce8e564ef0347e2a40" @@ -6734,7 +6734,7 @@ postcss-convert-values@^2.3.4: postcss "^5.0.11" postcss-value-parser "^3.1.2" -postcss-cssnext@^3.0.2: +postcss-cssnext@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/postcss-cssnext/-/postcss-cssnext-3.1.0.tgz#927dc29341a938254cde38ea60a923b9dfedead9" dependencies: @@ -6847,7 +6847,7 @@ postcss-image-set-polyfill@^0.3.5: postcss "^6.0.1" postcss-media-query-parser "^0.2.3" -postcss-import@^11.0.0: +postcss-import@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-11.1.0.tgz#55c9362c9192994ec68865d224419df1db2981f0" dependencies: @@ -7106,7 +7106,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 source-map "^0.5.6" supports-color "^3.2.3" -postcss@^6.0, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.14, postcss@^6.0.17, postcss@^6.0.18, postcss@^6.0.5, postcss@^6.0.6: +postcss@^6.0, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.14, postcss@^6.0.17, postcss@^6.0.18, postcss@^6.0.21, postcss@^6.0.5, postcss@^6.0.6: version "6.0.21" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.21.tgz#8265662694eddf9e9a5960db6da33c39e4cd069d" dependencies: @@ -7226,7 +7226,7 @@ process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" -progress-bar-webpack-plugin@^1.10.0: +progress-bar-webpack-plugin@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/progress-bar-webpack-plugin/-/progress-bar-webpack-plugin-1.11.0.tgz#4f801288443c55ec029b20cbfdcbf3e1dc17f852" dependencies: @@ -7420,7 +7420,7 @@ rc@^1.1.2, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^16.2.0: +react-dom@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.3.1.tgz#6a3c90a4fb62f915bdbcf6204422d93a7d4ca573" dependencies: @@ -7429,7 +7429,7 @@ react-dom@^16.2.0: object-assign "^4.1.1" prop-types "^15.6.0" -react@^16.2.0: +react@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/react/-/react-16.3.1.tgz#4a2da433d471251c69b6033ada30e2ed1202cfd8" dependencies: @@ -8913,7 +8913,7 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" -walk-sync@^0.3.1: +walk-sync@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.2.tgz#4827280afc42d0e035367c4a4e31eeac0d136f75" dependencies: @@ -8953,7 +8953,7 @@ web-resource-inliner@^4.2.0: valid-data-url "^0.1.4" xtend "^4.0.0" -webpack-node-externals@^1.6.0: +webpack-node-externals@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" From 89b75cf5ade159f4dfb4cc8ab9ff4ad247a9db1a Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 21:44:39 +0200 Subject: [PATCH 08/16] moved the code for the creation of a `built-in` variable to a utils file --- library/lib/webpack-utils.js | 42 +++++++++++++++ library/webpack-plugins/merge-css-plugin.js | 34 ++++--------- .../webpack-plugins/react-universal-plugin.js | 51 ++++++++----------- .../websocket-communication-plugin.js | 34 ++++--------- 4 files changed, 82 insertions(+), 79 deletions(-) create mode 100644 library/lib/webpack-utils.js diff --git a/library/lib/webpack-utils.js b/library/lib/webpack-utils.js new file mode 100644 index 00000000..638c7954 --- /dev/null +++ b/library/lib/webpack-utils.js @@ -0,0 +1,42 @@ +const ConstDependency = require('webpack/lib/dependencies/ConstDependency') +const NullFactory = require('webpack/lib/NullFactory') +const ParserHelpers = require('webpack/lib/ParserHelpers') + +module.exports = { + addBuiltInVariable +} + +// code copied from ExtendedApiPlugin +function addBuiltInVariable({ + compilation, normalModuleFactory, pluginName, + variableName, type, abbreviation, createValue +}) { + + compilation.dependencyFactories.set(ConstDependency, new NullFactory()) + compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) + + const { mainTemplate } = compilation + + const targetLocation = `${mainTemplate.requireFn}.${abbreviation}` + + mainTemplate.hooks.globalHash.tap(pluginName, () => true) + mainTemplate.hooks.requireExtensions.tap(pluginName, (source, chunk, hash) => { + const value = JSON.stringify(createValue(source, chunk, hash)) + const code = [ + source, + '', + `// ${variableName}`, + `${targetLocation} = ${value};` + ] + + return code.join('\n') + }) + + normalModuleFactory.hooks.parser.for('javascript/auto').tap(pluginName, addParserHooks) + normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(pluginName, addParserHooks) + + function addParserHooks(parser, parserOptions) { + parser.hooks.expression.for(variableName).tap(pluginName, ParserHelpers.toConstantDependency(parser, targetLocation)) + parser.hooks.evaluateTypeof.for(variableName).tap(pluginName, ParserHelpers.evaluateToString(type)) + } +} diff --git a/library/webpack-plugins/merge-css-plugin.js b/library/webpack-plugins/merge-css-plugin.js index cbf8fe51..e758811d 100644 --- a/library/webpack-plugins/merge-css-plugin.js +++ b/library/webpack-plugins/merge-css-plugin.js @@ -13,12 +13,10 @@ }) */ -const ConstDependency = require('webpack/lib/dependencies/ConstDependency') -const NullFactory = require('webpack/lib/NullFactory') -const ParserHelpers = require('webpack/lib/ParserHelpers') const crypto = require('crypto') const { ConcatSource, RawSource } = require('webpack-sources') const { SyncHook } = require('tapable') +const { addBuiltInVariable } = require('../lib/webpack-utils') const p = 'merge-css-plugin' @@ -104,29 +102,15 @@ module.exports = function mergeCssPlugin() { }) }) - // make sure the __webpack_css_chunk_hashes__ is available in modules (code copied from ExtendedApiPlugin) - compilation.dependencyFactories.set(ConstDependency, new NullFactory()) - compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { - - const cssHashes = chunkCssHashes.get(chunk) || [] - - const buf = [ - source, - '', - '// __webpack_css_chunk_hashes__', - `${compilation.mainTemplate.requireFn}.cch = ${JSON.stringify(cssHashes)};` - ] - return buf.join('\n') + // make sure the __webpack_css_chunk_hashes__ is available in modules + addBuiltInVariable({ + compilation, normalModuleFactory, + pluginName: p, + variableName: '__webpack_css_chunk_hashes__', + abbreviation: 'cch', + type: 'array', + createValue: (source, chunk, hash) => chunkCssHashes.get(chunk) || [] }) - compilation.mainTemplate.hooks.globalHash.tap(p, () => true) - normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) - normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) - - function addParserHooks(parser, parserOptions) { - parser.hooks.expression.for(`__webpack_css_chunk_hashes__`).tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.cch')) - parser.hooks.evaluateTypeof.for(`__webpack_css_chunk_hashes__`).tap(p, ParserHelpers.evaluateToString('string')) - } // merge css assets compilation.hooks.additionalChunkAssets.tap(p, chunks => { diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index 62a9c21a..65661484 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -1,13 +1,11 @@ const Compiler = require('webpack/lib/Compiler') -const ConstDependency = require('webpack/lib/dependencies/ConstDependency') const ImportDependency = require('webpack/lib/dependencies/ImportDependency') -const NullFactory = require('webpack/lib/NullFactory') -const ParserHelpers = require('webpack/lib/ParserHelpers') const RawModule = require('webpack/lib/RawModule') const Stats = require('webpack/lib/Stats') const WebpackOptionsApply = require('webpack/lib/WebpackOptionsApply') const WebpackOptionsDefaulter = require('webpack/lib/WebpackOptionsDefaulter') const { ReplaceSource } = require('webpack-sources') +const { addBuiltInVariable } = require('../lib/webpack-utils') const { relative } = require('path') /* @@ -151,36 +149,27 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { } }) - // make sure the __webpack_js_chunk_information__ is available in modules (code copied from ExtendedApiPlugin) + // make sure the __webpack_js_chunk_information__ is available in modules compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { - compilation.dependencyFactories.set(ConstDependency, new NullFactory()) - compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { - - // get the manifest from the client compilation - const [{ _kaliber_chunk_manifest_: manifest }] = compilation.children - - // find univeral modules in the current chunk (client chunk names) and grab their filenames (uniquely) - const universalChunkNames = chunk.getModules() - .filter(x => x.resource && x.resource.endsWith('?universal')) - .map(x => relative(compiler.context, x.resource.replace('?universal', ''))) - - const buf = [ - source, - '', - '// __webpack_js_chunk_information__', - `${compilation.mainTemplate.requireFn}.jci = ${JSON.stringify({ universalChunkNames, manifest })};` - ] - return buf.join('\n') - }) - compilation.mainTemplate.hooks.globalHash.tap(p, () => true) - normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) - normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) - function addParserHooks(parser, parserOptions) { - parser.hooks.expression.for('__webpack_js_chunk_information__').tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.jci')) - parser.hooks.evaluateTypeof.for('__webpack_js_chunk_information__').tap(p, ParserHelpers.evaluateToString('array')) - } + addBuiltInVariable({ + compilation, normalModuleFactory, + pluginName: p, + variableName: '__webpack_js_chunk_information__', + abbreviation: 'jci', + type: 'object', + createValue: (source, chunk, hash) => { + // get the manifest from the client compilation + const [{ _kaliber_chunk_manifest_: manifest }] = compilation.children + + // find univeral modules in the current chunk (client chunk names) and grab their filenames (uniquely) + const universalChunkNames = chunk.getModules() + .filter(x => x.resource && x.resource.endsWith('?universal')) + .map(x => relative(compiler.context, x.resource.replace('?universal', ''))) + + return { universalChunkNames, manifest } + } + }) }) } } diff --git a/library/webpack-plugins/websocket-communication-plugin.js b/library/webpack-plugins/websocket-communication-plugin.js index d58965b9..9c547c2e 100644 --- a/library/webpack-plugins/websocket-communication-plugin.js +++ b/library/webpack-plugins/websocket-communication-plugin.js @@ -12,12 +12,10 @@ message from `send`. */ -const { SyncHook } = require('tapable') -const ConstDependency = require('webpack/lib/dependencies/ConstDependency') -const NullFactory = require('webpack/lib/NullFactory') -const ParserHelpers = require('webpack/lib/ParserHelpers') const net = require('net') const ws = require('ws') +const { SyncHook } = require('tapable') +const { addBuiltInVariable } = require('../lib/webpack-utils') const p = 'websocket-communication-plugin' @@ -43,27 +41,17 @@ module.exports = function websocketCommunicationPlugin() { // wait for a free port before we start compiling compiler.hooks.beforeCompile.tapPromise(p, params => freePort.then(found => { port = found })) - // make sure the __webpack_websocket_port__ is available in modules (code copied from ExtendedApiPlugin) + // make sure the __webpack_websocket_port__ is available in modules compiler.hooks.compilation.tap(p, (compilation, { normalModuleFactory }) => { - compilation.dependencyFactories.set(ConstDependency, new NullFactory()) - compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()) - compilation.mainTemplate.hooks.requireExtensions.tap(p, function(source, chunk, hash) { - const buf = [ - source, - '', - '// __webpack_websocket_port__', - `${compilation.mainTemplate.requireFn}.wsp = ${port};` - ] - return buf.join('\n') + + addBuiltInVariable({ + compilation, normalModuleFactory, + pluginName: p, + variableName: '__webpack_websocket_port__', + abbreviation: 'wsp', + type: 'number', + createValue: (source, chunk, hash) => port }) - compilation.mainTemplate.hooks.globalHash.tap(p, () => true) - normalModuleFactory.hooks.parser.for('javascript/auto').tap(p, addParserHooks) - normalModuleFactory.hooks.parser.for('javascript/dynamic').tap(p, addParserHooks) - - function addParserHooks(parser, parserOptions) { - parser.hooks.expression.for('__webpack_websocket_port__').tap(p, ParserHelpers.toConstantDependency(parser, '__webpack_require__.wsp')) - parser.hooks.evaluateTypeof.for('__webpack_websocket_port__').tap(p, ParserHelpers.evaluateToString('string')) - } }) } } From 44e1197f70c43ada9336cfd8c9103f8523a21889 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:01:23 +0200 Subject: [PATCH 09/16] changed syntax to be nodejs 6 compatible --- example/src/test/test.html.js | 20 +++++++++---------- library/lib/build.js | 14 ++++++------- .../webpack-plugins/chunk-manifest-plugin.js | 7 +++---- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/example/src/test/test.html.js b/example/src/test/test.html.js index efabb672..88e83e46 100644 --- a/example/src/test/test.html.js +++ b/example/src/test/test.html.js @@ -3,14 +3,12 @@ import shared from '/partials/shared' import '/partials/Test?universal' import SharedComponent from '/partials/SharedComponent?universal' -export default function() { - return ( - {head('test')} - - {shared} - - Test - - - ) -} +export default ( + {head('test')} + + {shared} + + Test + + +) diff --git a/library/lib/build.js b/library/lib/build.js index a7824e81..cc8ae03b 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -174,10 +174,9 @@ module.exports = function build({ watch }) { }, resolve: resolveOptions(), resolveLoader: resolveLoaderOptions(), - module: { - unsafeCache: false, - ...moduleOptions() - }, + module: Object.assign({ + unsafeCache: false + }, moduleOptions()), plugins: [ ...pluginsOptions().all(), ...pluginsOptions().web() @@ -325,10 +324,9 @@ module.exports = function build({ watch }) { else runOnce(compilationComplete) function createCompiler(entries) { - return webpack({ - entry: entries, - ...nodeOptions() - }) + return webpack(Object.assign({ + entry: entries + }, nodeOptions())) } function compilationComplete(err, stats) { diff --git a/library/webpack-plugins/chunk-manifest-plugin.js b/library/webpack-plugins/chunk-manifest-plugin.js index af1c4a94..9c94ea95 100644 --- a/library/webpack-plugins/chunk-manifest-plugin.js +++ b/library/webpack-plugins/chunk-manifest-plugin.js @@ -36,12 +36,11 @@ module.exports = function chunkManifestPlugin() { const isShared = groups.length > 1 const [group] = groups - chunkAssets[chunk.name] = { + chunkAssets[chunk.name] = Object.assign({ filename, hasRuntime: chunk.hasRuntime(), - isShared, - ...(!isShared && { dependencies: group.chunks.filter(x => x !== chunk).map(x => x.name) }) - } + isShared + }, !isShared && { dependencies: group.chunks.filter(x => x !== chunk).map(x => x.name) }) }) compilation.hooks.additionalChunkAssets.tap(p, chunks => { From 4c114f7118597bd17f92e4ad55f772ae693162e0 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:04:05 +0200 Subject: [PATCH 10/16] removed unneeded dependencies --- example/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/package.json b/example/package.json index f6051ea9..ab1160f4 100644 --- a/example/package.json +++ b/example/package.json @@ -18,8 +18,6 @@ "firebase-admin": "^5.12.0", "mjml": "^4.0.3", "normalize.css": "^8.0.0", - "react": "^16.3.1", - "react-dom": "^16.3.1", "xml": "^1.0.1" } } \ No newline at end of file From 611b0d9dc41b0185b7301a0da9670e794def903f Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:04:31 +0200 Subject: [PATCH 11/16] set most likely version number of the breaking change in the readme --- library/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/README.md b/library/README.md index a4eb4fab..4bd81780 100644 --- a/library/README.md +++ b/library/README.md @@ -2,7 +2,7 @@ Breaking changes: -- v0.0.?? - `chunk-manifest.json` changed +- v0.0.51 - `chunk-manifest.json` changed - v0.0.47 - Universal apps no longer have an extra `
` around the root-app-node and the script-tag. - v0.0.44 - `*.entry.css` are now also hashed, use `css-manifest.json` to obtain the names - v0.0.41 - `*.*.js` are no longer all treated as templates, by default only `.html.js`, `.txt.js` and `.json.js` are considered From 56a6a4b0f9b33fde06240a308a00a68e4373ca2d Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:05:32 +0200 Subject: [PATCH 12/16] removed useless comments --- library/lib/build.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/lib/build.js b/library/lib/build.js index cc8ae03b..95deaee9 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -164,7 +164,7 @@ module.exports = function build({ watch }) { new UglifyJsPlugin({ cache: true, parallel: true, - sourceMap: true // this one is important + sourceMap: true }) ], splitChunks: { @@ -203,7 +203,6 @@ module.exports = function build({ watch }) { function moduleOptions() { return { - // noParse: https://webpack.js.org/configuration/module/#module-noparse rules: [{ oneOf: [ { From 04eaf0c7152cfc9df559174ba80c21af4e25a1cc Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:13:37 +0200 Subject: [PATCH 13/16] changed `done` to `callback` to be more consisten --- .../webpack-plugins/make-additional-entries-plugin.js | 8 ++++---- library/webpack-plugins/react-universal-plugin.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/webpack-plugins/make-additional-entries-plugin.js b/library/webpack-plugins/make-additional-entries-plugin.js index 10b1ca87..254fb7bd 100644 --- a/library/webpack-plugins/make-additional-entries-plugin.js +++ b/library/webpack-plugins/make-additional-entries-plugin.js @@ -9,16 +9,16 @@ Usage from other plugins: - compiler.hooks.makeAdditionalEntries.tapAsync('plugin-name', (compilation, createEntries, done) => { + compiler.hooks.makeAdditionalEntries.tapAsync('plugin-name', (compilation, createEntries, callback) => { // if you want to add new entries - createEntries({ name: path }, done) + createEntries({ name: path }, callback) // If you don't want to create entries - done() + callback() // when you need to signal an error - done(err) + callback(err) }) and diff --git a/library/webpack-plugins/react-universal-plugin.js b/library/webpack-plugins/react-universal-plugin.js index 65661484..86b5d020 100644 --- a/library/webpack-plugins/react-universal-plugin.js +++ b/library/webpack-plugins/react-universal-plugin.js @@ -39,7 +39,7 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { compiler.hooks.compilation.tap(p, c => { compilation = c }) webCompiler.hooks.compilation.tap(p, (webCompilation, { normalModuleFactory }) => { normalModuleFactory.hooks.createModule.tap(p, data => { - const path = data.resourceResolveData.path + const { path } = data.resourceResolveData if (!path.endsWith('.js') && !path.endsWith('.json')) { const parentCompilationModule = compilation.findModule(data.request) if (parentCompilationModule) { @@ -119,8 +119,8 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { }) // tell the web compiler to compile, emit the assets and notify the appropriate plugins - // Note, we can not use `make` because it's parralel - compiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, _, done) => { + // Note, we can not use `make` because it's parallel + compiler.hooks.makeAdditionalEntries.tapAsync(p, (compilation, _, callback) => { const startTime = Date.now() webCompiler.compile((err, webCompilation) => { @@ -138,14 +138,14 @@ module.exports = function reactUniversalPlugin (webCompilerOptions) { function finish(err, compilation) { if (err) { webCompiler.hooks.failed.call(err) - return done(err) + return callback(err) } const stats = new Stats(compilation) stats.startTime = startTime stats.endTime = Date.now() - webCompiler.hooks.done.callAsync(stats, done) + webCompiler.hooks.done.callAsync(stats, callback) } }) From d983f1fc788799619c5863488ed1eaaf2ad8f394 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Wed, 11 Apr 2018 22:21:30 +0200 Subject: [PATCH 14/16] updated to latest version --- library/package.json | 4 ++-- yarn.lock | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/library/package.json b/library/package.json index f4a806e5..7323d4d9 100644 --- a/library/package.json +++ b/library/package.json @@ -27,7 +27,7 @@ "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", - "caniuse-lite": "^1.0.30000824", + "caniuse-lite": "^1.0.30000827", "case-sensitive-paths-webpack-plugin": "^2.1.2", "compression": "^1.7.2", "cross-spawn": "^6.0.5", @@ -87,4 +87,4 @@ "bugs": { "url": "https://github.com/kaliberjs/build/issues" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 10ca3a2a..132d5415 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1741,10 +1741,14 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000824" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000824.tgz#bba3ff425296e04caa37fe426259206a7056551b" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000824: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805: version "1.0.30000824" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000824.tgz#de3bc1ba0bff4937302f8cb2a8632a8cc1c07f9a" +caniuse-lite@^1.0.30000827: + version "1.0.30000827" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000827.tgz#2dad2354e4810c3c9bb1cfc57f655c270c25fa52" + capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" From a29a97c2e6a6df85769e4610389709ff1f3beac5 Mon Sep 17 00:00:00 2001 From: EECOLOR Date: Sun, 15 Apr 2018 21:33:45 +0200 Subject: [PATCH 15/16] visual studio code told me (correctly) that `new` was not needed here --- library/lib/build.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/lib/build.js b/library/lib/build.js index 95deaee9..108de4bf 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -1,4 +1,4 @@ -// Better logging for deprecation and other errors +// @ts-ignore - Better logging for deprecation and other errors process.traceDeprecation = true process.on('unhandledRejection', (reason, p) => { console.log('Unhandled rejection of:\n', p, '\nReason:\n', reason) @@ -279,7 +279,7 @@ module.exports = function build({ watch }) { function pluginsOptions() { return { all: () => [ - new ProgressBarPlugin(), + ProgressBarPlugin(), watch && websocketCommunicationPlugin(), makeAdditionalEntriesPlugin(), new CaseSensitivePathsPlugin(), From 1058e60d64a91862260ebe49b3e87dfb72e5a0ac Mon Sep 17 00:00:00 2001 From: klaasman Date: Wed, 18 Apr 2018 10:29:04 +0200 Subject: [PATCH 16/16] `*.entry.css` classnames are no longer hashed --- library/README.md | 7 +++---- library/lib/build.js | 7 ++++++- library/webpack-loaders/css-loader.js | 19 ++++++++++++------- .../webpack-loaders/to-json-file-loader.js | 11 ----------- 4 files changed, 21 insertions(+), 23 deletions(-) delete mode 100644 library/webpack-loaders/to-json-file-loader.js diff --git a/library/README.md b/library/README.md index 22e0ec0e..f3bb2a37 100644 --- a/library/README.md +++ b/library/README.md @@ -2,15 +2,14 @@ Breaking changes: -- v0.0.51 - `chunk-manifest.json` changed +- v0.0.51 - `chunk-manifest.json` changed. `*.entry.css` classnames are no longer hashed. - v0.0.47 - Universal apps no longer have an extra `
` around the root-app-node and the script-tag. -- v0.0.44 - `*.entry.css` are now also hashed, use `css-manifest.json` to obtain the names +- v0.0.44 - `*.entry.css` filenames are now also hashed, use `css-manifest.json` to obtain the filenames - v0.0.41 - `*.*.js` are no longer all treated as templates, by default only `.html.js`, `.txt.js` and `.json.js` are considered - v0.0.40 - `src` is no longer treated as `node_modules`, use absolute paths (`/x`) to retrieve modules from subdirectories - v0.0.40 - Javascripts are now hashes, they require an additional import to load - v0.0.35 - Stylesheets are now hashes, they require an additional import to load - # Kaliber.js build An opinionated zero configuration build stack with React, PostCSS, Babel and Webpack as major ingredients. @@ -75,7 +74,7 @@ Ruby popularized 'convention over configuration', this library has a set of conv - `src` - Source files live in the `src` directory. - `target` - Compiled / processed files are stored in the `target` directory. - `src/**/*.entry.js` - Compiled as a separate `.js` webpack entry. -- `src/**/*.entry.css` - Compiled as a separate `.css` webpack entry, for each CSS file a `.json` file is generated containing the class names. +- `src/**/*.entry.css` - Compiled as a separate `.css` webpack entry (*without* hashed classnames). - `src/**/*.{type}.js` - Compiled as webpack entry using a renderer associated with the type. - `{type}` refers to the renderer that is used - `html` - Expects JSX to be returned from the template diff --git a/library/lib/build.js b/library/lib/build.js index 108de4bf..aacd44dd 100644 --- a/library/lib/build.js +++ b/library/lib/build.js @@ -68,6 +68,11 @@ const babelLoader = { } } +const cssLoaderGlobalScope = { + loader: 'css-loader', + options: { globalScopeBehaviour: true } +} + const cssLoader = { loader: 'css-loader' } @@ -213,7 +218,7 @@ module.exports = function build({ watch }) { { test: /\.entry\.css$/, - loaders: ['to-json-file-loader', cssLoader] + loaders: [cssLoaderGlobalScope] }, { diff --git a/library/webpack-loaders/css-loader.js b/library/webpack-loaders/css-loader.js index c80c10f3..88806c6e 100644 --- a/library/webpack-loaders/css-loader.js +++ b/library/webpack-loaders/css-loader.js @@ -4,7 +4,9 @@ const { relative, dirname } = require('path') const isProduction = process.env.NODE_ENV === 'production' -function createPlugins(minifyOnly, { onExport, resolve, processUrl }) { +function createPlugins(loaderOptions, { onExport, resolve, processUrl }) { + const { minifyOnly = false, globalScopeBehaviour = false } = loaderOptions + return [ // these plugis need to run on each file individual file // look at the source of postcss-modules to see that it effectively runs all modules twice @@ -13,6 +15,7 @@ function createPlugins(minifyOnly, { onExport, resolve, processUrl }) { require('postcss-import')({ glob: true, resolve }), require('postcss-apply')(), // https://github.com/kaliberjs/build/issues/34 require('postcss-modules')({ + scopeBehaviour: globalScopeBehaviour ? 'global' : 'local', getJSON: (_, json) => { onExport(json) }, generateScopedName: isProduction ? '[hash:base64:5]' : '[folder]-[name]-[local]__[hash:base64:5]' }) @@ -40,9 +43,8 @@ module.exports = function CssLoader(source, map) { : Promise.resolve(url) } - const { minifyOnly = false } = loaderUtils.getOptions(this) || {} - - const plugins = createPlugins(minifyOnly, handlers) + const loaderOptions = loaderUtils.getOptions(this) || {} + const plugins = createPlugins(loaderOptions, handlers) const filename = relative(this.rootContext, this.resourcePath) const options = { from: this.resourcePath, @@ -61,9 +63,12 @@ module.exports = function CssLoader(source, map) { this.emitFile(filename, css, map.toJSON()) - exports.cssHash = require('crypto').createHash('md5').update(css).digest('hex') - - callback(null, exports) + if (loaderOptions.globalScopeBehaviour) { + callback(null, '// postcss-modules is disabled, no exports available') + } else { + exports.cssHash = require('crypto').createHash('md5').update(css).digest('hex') + callback(null, exports) + } }) .catch(e => { callback(e) }) diff --git a/library/webpack-loaders/to-json-file-loader.js b/library/webpack-loaders/to-json-file-loader.js deleted file mode 100644 index b820425f..00000000 --- a/library/webpack-loaders/to-json-file-loader.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - Emits the given source as a json file -*/ - -const { relative } = require('path') - -module.exports = function ToJsonFileLoader(source) { - const filename = relative(this.rootContext, this.resourcePath) - this.emitFile(filename + '.json', JSON.stringify(source)) - return '// json file was emitted' -}