From bdad1fe3b19376919d80b8f001cf2f5c654fc19e Mon Sep 17 00:00:00 2001 From: QWp6t Date: Tue, 7 Feb 2017 14:45:18 -0800 Subject: [PATCH] Use copy-globs-webpack-plugin (#1824) --- assets/build/util/interpolateName.js | 50 -------- assets/build/util/promisify.js | 21 ---- assets/build/webpack.config.js | 2 +- assets/build/webpack.plugin.copyglobs.js | 147 ----------------------- package.json | 1 + yarn.lock | 20 ++- 6 files changed, 11 insertions(+), 230 deletions(-) delete mode 100644 assets/build/util/interpolateName.js delete mode 100644 assets/build/util/promisify.js delete mode 100644 assets/build/webpack.plugin.copyglobs.js diff --git a/assets/build/util/interpolateName.js b/assets/build/util/interpolateName.js deleted file mode 100644 index d96490f..0000000 --- a/assets/build/util/interpolateName.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; // eslint-disable-line - -const path = require('path'); -const utils = require('loader-utils'); - -/** - * Generate output name from output pattern - * - * @link https://github.com/kevlened/copy-webpack-plugin/blob/323b1d74ef35ed2221637d8028b1bef854deb523/src/writeFile.js#L31-L65 - * @param {string} pattern - * @param {string} relativeFrom - * @param {binary} content - * @return {string} - */ -module.exports = (pattern, relativeFrom, content) => { - let webpackTo = pattern; - let resourcePath = relativeFrom; - - /* A hack so .dotted files don't get parsed as extensions */ - const basename = path.basename(resourcePath); - let dotRemoved = false; - if (basename[0] === '.') { - dotRemoved = true; - resourcePath = path.join(path.dirname(resourcePath), basename.slice(1)); - } - - /** - * If it doesn't have an extension, remove it from the pattern - * ie. [name].[ext] or [name][ext] both become [name] - */ - if (!path.extname(resourcePath)) { - webpackTo = webpackTo.replace(/\.?\[ext]/g, ''); - } - - /** - * A hack because loaderUtils.interpolateName doesn't - * find the right path if no directory is defined - * ie. [path] applied to 'file.txt' would return 'file' - */ - if (resourcePath.indexOf('/') < 0) { - resourcePath = `/${resourcePath}`; - } - - webpackTo = utils.interpolateName({ resourcePath }, webpackTo, { content }); - - if (dotRemoved) { - webpackTo = path.join(path.dirname(webpackTo), `.${path.basename(webpackTo)}`); - } - return webpackTo; -}; diff --git a/assets/build/util/promisify.js b/assets/build/util/promisify.js deleted file mode 100644 index 65a6455..0000000 --- a/assets/build/util/promisify.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Node-style asynchronous function. - * - * @callback nodeAsyncCallback - * @param {string|null} err - * @param {*} data - */ -/** - * Promisify node-style asynchronous functions - * - * @param {nodeAsyncCallback} fn - Function with node-style callback - * @param {this} [scope] - Scope to which the function should be bound. Default: fn - * @returns {Promise} - An instance of Promise - */ -module.exports = (fn, scope) => function callback() { - const args = [].slice.call(arguments); - return new Promise((resolve, reject) => { - args.push((err, data) => (err === null ? resolve(data) : reject(err))); - return fn.apply(scope || fn, args); - }); -}; diff --git a/assets/build/webpack.config.js b/assets/build/webpack.config.js index 10a5381..37ad99b 100644 --- a/assets/build/webpack.config.js +++ b/assets/build/webpack.config.js @@ -7,7 +7,7 @@ const autoprefixer = require('autoprefixer'); const CleanPlugin = require('clean-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const CopyGlobsPlugin = require('./webpack.plugin.copyglobs'); +const CopyGlobsPlugin = require('copy-globs-webpack-plugin'); const config = require('./config'); const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]'; diff --git a/assets/build/webpack.plugin.copyglobs.js b/assets/build/webpack.plugin.copyglobs.js deleted file mode 100644 index e7eb773..0000000 --- a/assets/build/webpack.plugin.copyglobs.js +++ /dev/null @@ -1,147 +0,0 @@ -'use strict'; // eslint-disable-line - -const fs = require('fs'); -const path = require('path'); -const glob = require('glob'); -const utils = require('loader-utils'); -const includes = require('lodash/includes'); - -const interpolateName = require('./util/interpolateName'); -const promisify = require('./util/promisify'); - -const fixPath = v => v.replace(/\\/g, '/'); -const errorMsg = msg => `\x1b[31m${msg}\x1b[0m`; - -const GLOB_CWD_AUTO = null; - -const globAsync = promisify(glob); -const statAsync = promisify(fs.stat); -const readFileAsync = promisify(fs.readFile); - -class PatternUndefinedError extends Error { - constructor() { - super(errorMsg('[copy-globs] You must provide glob pattern.')); - } -} - -class ArgsArrayError extends TypeError { - constructor() { - super(errorMsg( - '[copy-globs] pattern cannot be an array.\n' + - 'For multiple folders, use something like:\n\n' + - ' +(images|fonts)/**/*\n\n' + - 'See also: https://github.com/isaacs/node-glob#glob-primer\n' - )); - } -} - -/** - * Throws an error if pattern is an array or undefined - * - * @param pattern - */ -const testPattern = (pattern) => { - if (pattern === undefined) { - throw new PatternUndefinedError(); - } - if (Array.isArray(pattern)) { - throw new ArgsArrayError(); - } -}; - -const normalizeArguments = (input) => { - testPattern(input); - const options = {}; - if (typeof input === 'string') { - options.pattern = input; - } else { - testPattern(input.pattern); - return input; - } - return options; -}; - -module.exports = class { - constructor(o) { - const options = normalizeArguments(o); - this.pattern = options.pattern; - this.disable = options.disable; - this.output = options.output || '[path][name].[ext]'; - this.globOptions = Object.assign(options.globOptions || {}, { cwd: GLOB_CWD_AUTO }); - this.globOptions.nodir = true; - this.manifest = options.manifest || {}; - this.files = []; - this.started = false; - } - apply(compiler) { - if (this.disable) { - return; - } - this.compiler = compiler; - this.resolveWorkingDirectory(); - if (!this.started) { - compiler.plugin('emit', this.emitHandler.bind(this)); - compiler.plugin('after-emit', this.afterEmitHandler.bind(this)); - this.started = true; - } - } - emitHandler(compilation, callback) { - this.compilation = compilation; - globAsync(this.pattern, this.globOptions) - .then( - paths => Promise.all(paths.map(this.processAsset.bind(this))), - err => compilation.errors.push(err) - ) - .then(() => { - Object.keys(this.files).forEach((absoluteFrom) => { - const file = this.files[absoluteFrom]; - this.manifest[file.relativeFrom] = file.webpackTo; - this.compilation.assets[file.webpackTo] = { - size: () => file.stat.size, - source: () => file.content, - }; - }); - }) - .then(callback); - } - afterEmitHandler(compilation, callback) { - Object.keys(this.files) - .filter(absoluteFrom => !includes(compilation.fileDependencies, absoluteFrom)) - .forEach(absoluteFrom => compilation.fileDependencies.push(absoluteFrom)); - callback(); - } - resolveWorkingDirectory() { - if (this.globOptions.cwd === GLOB_CWD_AUTO) { - this.globOptions.cwd = this.compiler.options.context; - } - this.context = this.globOptions.cwd || this.compiler.options.context; - } - processAsset(relativeFrom) { - if (this.compilation.assets[relativeFrom]) { - return Promise.resolve(); - } - const absoluteFrom = path.resolve(this.context, relativeFrom); - return statAsync(absoluteFrom) - .then(stat => this.buildFileObject(relativeFrom, absoluteFrom, stat)) - .then(this.addAsset.bind(this)); - } - buildFileObject(relativeFrom, absoluteFrom, stat) { - return readFileAsync(absoluteFrom) - .then((content) => { - const hash = utils.getHashDigest(content); - const webpackTo = fixPath(interpolateName(this.output, relativeFrom, content)); - return { relativeFrom, absoluteFrom, stat, content, hash, webpackTo }; - }); - } - addAsset(file) { - const asset = this.getAsset(file.absoluteFrom); - if (asset && asset.hash === file.hash) { - return null; - } - this.files[file.absoluteFrom] = file; - return file; - } - getAsset(absoluteFrom) { - return this.files[absoluteFrom]; - } -}; diff --git a/package.json b/package.json index d6d4514..f8b3a2c 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "buble": "^0.15.2", "buble-loader": "^0.4.0", "clean-webpack-plugin": "^0.1.15", + "copy-globs-webpack-plugin": "^0.1.0", "css-loader": "^0.26.1", "cssnano": "^3.10.0", "eslint": "^3.14.0", diff --git a/yarn.lock b/yarn.lock index 58aade8..3829e0f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -959,6 +959,13 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-globs-webpack-plugin@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/copy-globs-webpack-plugin/-/copy-globs-webpack-plugin-0.1.0.tgz#20123c42b4754342bbba249472eb7b88b9bc1c5c" + dependencies: + glob "^7.1.1" + loader-utils "^0.2.16" + core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -4063,16 +4070,7 @@ postcss-zindex@^2.0.1: postcss "^5.0.4" uniqs "^2.0.0" -postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.8, postcss@^5.2.9: - version "5.2.10" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.10.tgz#b58b64e04f66f838b7bc7cb41f7dac168568a945" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.1.2" - -postcss@^5.2.11: +postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.11, postcss@^5.2.8, postcss@^5.2.9: version "5.2.11" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761" dependencies: @@ -4923,7 +4921,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: +supports-color@^3.1.0, supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: