Use copy-globs-webpack-plugin (#1824)
This commit is contained in:
@@ -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;
|
|
||||||
};
|
|
||||||
@@ -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);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -7,7 +7,7 @@ const autoprefixer = require('autoprefixer');
|
|||||||
const CleanPlugin = require('clean-webpack-plugin');
|
const CleanPlugin = require('clean-webpack-plugin');
|
||||||
const ExtractTextPlugin = require('extract-text-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 config = require('./config');
|
||||||
|
|
||||||
const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
|
const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
|
||||||
|
|||||||
@@ -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];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
"buble": "^0.15.2",
|
"buble": "^0.15.2",
|
||||||
"buble-loader": "^0.4.0",
|
"buble-loader": "^0.4.0",
|
||||||
"clean-webpack-plugin": "^0.1.15",
|
"clean-webpack-plugin": "^0.1.15",
|
||||||
|
"copy-globs-webpack-plugin": "^0.1.0",
|
||||||
"css-loader": "^0.26.1",
|
"css-loader": "^0.26.1",
|
||||||
"cssnano": "^3.10.0",
|
"cssnano": "^3.10.0",
|
||||||
"eslint": "^3.14.0",
|
"eslint": "^3.14.0",
|
||||||
|
|||||||
20
yarn.lock
20
yarn.lock
@@ -959,6 +959,13 @@ cookie@0.3.1:
|
|||||||
version "0.3.1"
|
version "0.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
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:
|
core-js@^2.4.0:
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
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"
|
postcss "^5.0.4"
|
||||||
uniqs "^2.0.0"
|
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:
|
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.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:
|
|
||||||
version "5.2.11"
|
version "5.2.11"
|
||||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761"
|
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.11.tgz#ff29bcd6d2efb98bfe08a022055ec599bbe7b761"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4923,7 +4921,7 @@ supports-color@^2.0.0:
|
|||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
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"
|
version "3.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user