Socket
Socket
Sign inDemoInstall

copy-webpack-plugin

Package Overview
Dependencies
Maintainers
6
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

copy-webpack-plugin - npm Package Compare versions

Comparing version 6.2.1 to 6.3.0

8

CHANGELOG.md

@@ -5,2 +5,10 @@ # Changelog

## [6.3.0](https://github.com/webpack-contrib/copy-webpack-plugin/compare/v6.2.1...v6.3.0) (2020-11-03)
### Features
* added the `sourceFilename` info (original source filename) to assets info ([#542](https://github.com/webpack-contrib/copy-webpack-plugin/issues/542)) ([db2e3bf](https://github.com/webpack-contrib/copy-webpack-plugin/commit/db2e3bfae9322592c3a9af1e45d25df165b6b4e0))
* persistent cache between compilations (webpack@5 only) ([#541](https://github.com/webpack-contrib/copy-webpack-plugin/issues/541)) ([c892451](https://github.com/webpack-contrib/copy-webpack-plugin/commit/c8924512a34391ce92715a2b61fc4b0b91a9e10f))
### [6.2.1](https://github.com/webpack-contrib/copy-webpack-plugin/compare/v6.2.0...v6.2.1) (2020-10-09)

@@ -7,0 +15,0 @@

421

dist/index.js

@@ -60,6 +60,43 @@ "use strict";

this.options = options.options || {};
} // eslint-disable-next-line class-methods-use-this
}
static async createSnapshot(compilation, startTime, dependency) {
if (!compilation.fileSystemInfo) {
return;
} // eslint-disable-next-line consistent-return
async runPattern(compiler, compilation, logger, inputPattern) {
return new Promise((resolve, reject) => {
compilation.fileSystemInfo.createSnapshot(startTime, [dependency], // eslint-disable-next-line no-undefined
undefined, // eslint-disable-next-line no-undefined
undefined, null, (error, snapshot) => {
if (error) {
reject(error);
return;
}
resolve(snapshot);
});
});
}
static async checkSnapshotValid(compilation, snapshot) {
if (!compilation.fileSystemInfo) {
return;
} // eslint-disable-next-line consistent-return
return new Promise((resolve, reject) => {
compilation.fileSystemInfo.checkSnapshotValid(snapshot, (error, isValid) => {
if (error) {
reject(error);
return;
}
resolve(isValid);
});
});
}
static async runPattern(compiler, compilation, logger, cache, inputPattern, index) {
const pattern = typeof inputPattern === 'string' ? {

@@ -72,4 +109,5 @@ from: inputPattern

pattern.to = _path.default.normalize(typeof pattern.to !== 'undefined' ? pattern.to : '');
pattern.context = _path.default.normalize(typeof pattern.context !== 'undefined' ? !_path.default.isAbsolute(pattern.context) ? _path.default.join(compiler.options.context, pattern.context) : pattern.context : compiler.options.context);
logger.debug(`processing from "${pattern.from}" to "${pattern.to}"`);
pattern.compilerContext = compiler.context;
pattern.context = _path.default.normalize(typeof pattern.context !== 'undefined' ? !_path.default.isAbsolute(pattern.context) ? _path.default.join(pattern.compilerContext, pattern.context) : pattern.context : pattern.compilerContext);
logger.log(`starting to process a pattern from '${pattern.from}' using '${pattern.context}' context to '${pattern.to}'...`);

@@ -101,3 +139,3 @@ const isToDirectory = _path.default.extname(pattern.to) === '' || pattern.to.slice(-1) === _path.default.sep;

logger.debug(`getting stats for "${pattern.absoluteFrom}" to determinate "fromType"`);
logger.debug(`getting stats for '${pattern.absoluteFrom}'...`);
const {

@@ -116,4 +154,8 @@ inputFileSystem

pattern.fromType = 'dir';
logger.debug(`determined '${pattern.absoluteFrom}' is a directory`);
} else if (stats.isFile()) {
pattern.fromType = 'file';
logger.debug(`determined '${pattern.absoluteFrom}' is a file`);
} else {
logger.debug(`determined '${pattern.absoluteFrom}' is a glob`);
}

@@ -139,5 +181,4 @@ } // eslint-disable-next-line no-param-reassign

case 'dir':
logger.debug(`determined "${pattern.absoluteFrom}" is a directory`);
compilation.contextDependencies.add(pattern.absoluteFrom);
logger.debug(`add "${pattern.absoluteFrom}" as a context dependency`);
logger.debug(`added '${pattern.absoluteFrom}' as a context dependency`);
/* eslint-disable no-param-reassign */

@@ -158,5 +199,4 @@

case 'file':
logger.debug(`determined "${pattern.absoluteFrom}" is a file`);
compilation.fileDependencies.add(pattern.absoluteFrom);
logger.debug(`add "${pattern.absoluteFrom}" as a file dependency`);
logger.debug(`added '${pattern.absoluteFrom}' as a file dependency`);
/* eslint-disable no-param-reassign */

@@ -177,8 +217,6 @@

{
logger.debug(`determined "${pattern.absoluteFrom}" is a glob`);
const contextDependencies = _path.default.normalize((0, _globParent.default)(pattern.absoluteFrom));
compilation.contextDependencies.add(contextDependencies);
logger.debug(`add "${contextDependencies}" as a context dependency`);
logger.debug(`added '${contextDependencies}' as a context dependency`);
/* eslint-disable no-param-reassign */

@@ -192,14 +230,21 @@

logger.log(`begin globbing "${pattern.glob}" with a context of "${pattern.context}"`);
const paths = await (0, _globby.default)(pattern.glob, pattern.globOptions);
logger.log(`begin globbing '${pattern.glob}'...`);
let paths;
try {
paths = await (0, _globby.default)(pattern.glob, pattern.globOptions);
} catch (error) {
compilation.errors.push(error);
return;
}
if (paths.length === 0) {
if (pattern.noErrorOnMissing) {
return Promise.resolve();
logger.log(`finished to process a pattern from '${pattern.from}' using '${pattern.context}' context to '${pattern.to}'`);
return;
}
const missingError = new Error(`unable to locate "${pattern.from}" at "${pattern.absoluteFrom}"`);
logger.error(missingError.message);
const missingError = new Error(`unable to locate '${pattern.glob}' glob`);
compilation.errors.push(missingError);
return Promise.resolve();
return;
}

@@ -214,3 +259,15 @@

if (pattern.filter) {
const isFiltered = await pattern.filter(item.path);
let isFiltered;
try {
isFiltered = await pattern.filter(item.path);
} catch (error) {
compilation.errors.push(error);
return false;
}
if (!isFiltered) {
logger.log(`skip '${item.path}', because it was filtered`);
}
return isFiltered ? item : false;

@@ -223,3 +280,5 @@ }

if (filteredPaths.length === 0) {
return Promise.resolve();
// TODO should be error in the next major release
logger.log(`finished to process a pattern from '${pattern.from}' using '${pattern.context}' context to '${pattern.to}'`);
return;
}

@@ -229,116 +288,235 @@

const from = item.path;
logger.debug(`found "${from}"`); // `globby`/`fast-glob` return the relative path when the path contains special characters on windows
logger.debug(`found '${from}'`); // `globby`/`fast-glob` return the relative path when the path contains special characters on windows
const absoluteFrom = _path.default.resolve(pattern.context, from);
const absoluteFilename = _path.default.resolve(pattern.context, from);
const relativeFrom = pattern.flatten ? _path.default.basename(absoluteFrom) : _path.default.relative(pattern.context, absoluteFrom);
let webpackTo = pattern.toType === 'dir' ? _path.default.join(pattern.to, relativeFrom) : pattern.to;
const relativeFrom = pattern.flatten ? _path.default.basename(absoluteFilename) : _path.default.relative(pattern.context, absoluteFilename);
let filename = pattern.toType === 'dir' ? _path.default.join(pattern.to, relativeFrom) : pattern.to;
if (_path.default.isAbsolute(webpackTo)) {
webpackTo = _path.default.relative(compiler.options.output.path, webpackTo);
if (_path.default.isAbsolute(filename)) {
filename = _path.default.relative(compiler.options.output.path, filename);
}
logger.log(`determined that "${from}" should write to "${webpackTo}"`);
logger.log(`determined that '${from}' should write to '${filename}'`);
const sourceFilename = (0, _normalizePath.default)(_path.default.relative(pattern.compilerContext, absoluteFilename));
return {
absoluteFrom,
relativeFrom,
webpackTo
absoluteFilename,
sourceFilename,
filename
};
});
return Promise.all(files.map(async file => {
// If this came from a glob, add it to the file watchlist
if (pattern.fromType === 'glob') {
logger.debug(`add ${file.absoluteFrom} as fileDependencies`);
compilation.fileDependencies.add(file.absoluteFrom);
}
let assets;
logger.debug(`reading "${file.absoluteFrom}" to write to assets`);
let data;
try {
assets = await Promise.all(files.map(async file => {
const {
absoluteFilename,
sourceFilename,
filename
} = file;
const result = {
absoluteFilename,
sourceFilename,
filename,
force: pattern.force
}; // If this came from a glob, add it to the file dependencies
try {
data = await (0, _promisify.readFile)(inputFileSystem, file.absoluteFrom);
} catch (error) {
compilation.errors.push(error);
return;
}
if (pattern.fromType === 'glob') {
compilation.fileDependencies.add(absoluteFilename);
logger.debug(`added '${absoluteFilename}' as a file dependency`);
}
if (pattern.transform) {
logger.log(`transforming content for "${file.absoluteFrom}"`);
if (cache) {
let cacheEntry;
logger.debug(`getting cache for '${absoluteFilename}'...`);
if (pattern.cacheTransform) {
const cacheDirectory = pattern.cacheTransform.directory ? pattern.cacheTransform.directory : typeof pattern.cacheTransform === 'string' ? pattern.cacheTransform : (0, _findCacheDir.default)({
name: 'copy-webpack-plugin'
}) || _os.default.tmpdir();
let defaultCacheKeys = {
version: _package.version,
transform: pattern.transform,
contentHash: _crypto.default.createHash('md4').update(data).digest('hex')
};
try {
cacheEntry = await cache.getPromise(`${sourceFilename}|${index}`, null);
} catch (error) {
compilation.errors.push(error);
return;
}
if (typeof pattern.cacheTransform.keys === 'function') {
defaultCacheKeys = await pattern.cacheTransform.keys(defaultCacheKeys, file.absoluteFrom);
if (cacheEntry) {
logger.debug(`found cache for '${absoluteFilename}'...`);
let isValidSnapshot;
logger.debug(`checking snapshot on valid for '${absoluteFilename}'...`);
try {
isValidSnapshot = await CopyPlugin.checkSnapshotValid(compilation, cacheEntry.snapshot);
} catch (error) {
compilation.errors.push(error);
return;
}
if (isValidSnapshot) {
logger.debug(`snapshot for '${absoluteFilename}' is valid`);
result.source = cacheEntry.source;
} else {
logger.debug(`snapshot for '${absoluteFilename}' is invalid`);
}
} else {
defaultCacheKeys = { ...defaultCacheKeys,
...pattern.cacheTransform.keys
};
logger.debug(`missed cache for '${absoluteFilename}'`);
}
}
const cacheKeys = (0, _serializeJavascript.default)(defaultCacheKeys);
if (!result.source) {
let startTime;
if (cache) {
startTime = Date.now();
}
logger.debug(`reading '${absoluteFilename}'...`);
let data;
try {
const result = await _cacache.default.get(cacheDirectory, cacheKeys);
logger.debug(`getting cached transformation for "${file.absoluteFrom}"`);
({
data
} = result);
} catch (_ignoreError) {
data = await pattern.transform(data, file.absoluteFrom);
logger.debug(`caching transformation for "${file.absoluteFrom}"`);
await _cacache.default.put(cacheDirectory, cacheKeys, data);
data = await (0, _promisify.readFile)(inputFileSystem, absoluteFilename);
} catch (error) {
compilation.errors.push(error);
return;
}
} else {
data = await pattern.transform(data, file.absoluteFrom);
logger.debug(`read '${absoluteFilename}'`);
result.source = new RawSource(data);
if (cache) {
let snapshot;
logger.debug(`creating snapshot for '${absoluteFilename}'...`);
try {
snapshot = await CopyPlugin.createSnapshot(compilation, startTime, sourceFilename);
} catch (error) {
compilation.errors.push(error);
return;
}
if (snapshot) {
logger.debug(`created snapshot for '${absoluteFilename}'`);
logger.debug(`storing cache for '${absoluteFilename}'...`);
try {
await cache.storePromise(`${sourceFilename}|${index}`, null, {
source: result.source,
snapshot
});
} catch (error) {
compilation.errors.push(error);
return;
}
logger.debug(`stored cache for '${absoluteFilename}'`);
}
}
}
}
if (pattern.toType === 'template') {
logger.log(`interpolating template "${file.webpackTo}" for "${file.relativeFrom}"`); // If it doesn't have an extension, remove it from the pattern
// ie. [name].[ext] or [name][ext] both become [name]
if (pattern.transform) {
logger.log(`transforming content for '${absoluteFilename}'...`);
const buffer = result.source.source();
if (!_path.default.extname(file.relativeFrom)) {
// eslint-disable-next-line no-param-reassign
file.webpackTo = file.webpackTo.replace(/\.?\[ext]/g, '');
} // eslint-disable-next-line no-param-reassign
if (pattern.cacheTransform) {
const defaultCacheKeys = {
version: _package.version,
sourceFilename,
transform: pattern.transform,
contentHash: _crypto.default.createHash('md4').update(buffer).digest('hex'),
index
};
const cacheKeys = `transform|${(0, _serializeJavascript.default)(typeof pattern.cacheTransform.keys === 'function' ? await pattern.cacheTransform.keys(defaultCacheKeys, absoluteFilename) : { ...defaultCacheKeys,
...pattern.cacheTransform.keys
})}`;
let cacheItem;
let cacheDirectory;
logger.debug(`getting transformation cache for '${absoluteFilename}'...`); // webpack@5 API
if (cache) {
cacheItem = cache.getItemCache(cacheKeys, cache.getLazyHashedEtag(result.source));
result.source = await cacheItem.getPromise();
} else {
cacheDirectory = pattern.cacheTransform.directory ? pattern.cacheTransform.directory : typeof pattern.cacheTransform === 'string' ? pattern.cacheTransform : (0, _findCacheDir.default)({
name: 'copy-webpack-plugin'
}) || _os.default.tmpdir();
let cached;
file.immutable = /\[(?:([^:\]]+):)?(?:hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi.test(file.webpackTo); // eslint-disable-next-line no-param-reassign
try {
cached = await _cacache.default.get(cacheDirectory, cacheKeys);
} catch (error) {
logger.debug(`no transformation cache for '${absoluteFilename}'...`);
} // eslint-disable-next-line no-undefined
file.webpackTo = _loaderUtils.default.interpolateName({
resourcePath: file.absoluteFrom
}, file.webpackTo, {
content: data,
context: pattern.context
}); // Bug in `loader-utils`, package convert `\\` to `/`, need fix in loader-utils
// eslint-disable-next-line no-param-reassign
file.webpackTo = _path.default.normalize(file.webpackTo);
}
result.source = cached ? new RawSource(cached.data) : undefined;
}
if (pattern.transformPath) {
logger.log(`transforming path "${file.webpackTo}" for "${file.absoluteFrom}"`); // eslint-disable-next-line no-param-reassign
logger.debug(result.source ? `found transformation cache for '${absoluteFilename}'` : `no transformation cache for '${absoluteFilename}'`);
file.immutable = false; // eslint-disable-next-line no-param-reassign
if (!result.source) {
const transformed = await pattern.transform(buffer, absoluteFilename);
result.source = new RawSource(transformed);
logger.debug(`caching transformation for '${absoluteFilename}'...`); // webpack@5 API
file.webpackTo = await pattern.transformPath(file.webpackTo, file.absoluteFrom);
} // eslint-disable-next-line no-param-reassign
if (cache) {
await cacheItem.storePromise(result.source);
} else {
try {
await _cacache.default.put(cacheDirectory, cacheKeys, transformed);
} catch (error) {
compilation.errors.push(error);
return;
}
}
logger.debug(`cached transformation for '${absoluteFilename}'`);
}
} else {
result.source = new RawSource(await pattern.transform(buffer, absoluteFilename));
}
}
file.data = data; // eslint-disable-next-line no-param-reassign
if (pattern.toType === 'template') {
logger.log(`interpolating template '${filename}' for '${sourceFilename}'...`); // If it doesn't have an extension, remove it from the pattern
// ie. [name].[ext] or [name][ext] both become [name]
file.targetPath = (0, _normalizePath.default)(file.webpackTo); // eslint-disable-next-line no-param-reassign
if (!_path.default.extname(absoluteFilename)) {
// eslint-disable-next-line no-param-reassign
result.filename = result.filename.replace(/\.?\[ext]/g, '');
} // eslint-disable-next-line no-param-reassign
file.force = pattern.force; // eslint-disable-next-line consistent-return
return file;
}));
result.immutable = /\[(?:([^:\]]+):)?(?:hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi.test(result.filename); // eslint-disable-next-line no-param-reassign
result.filename = _loaderUtils.default.interpolateName({
resourcePath: absoluteFilename
}, result.filename, {
content: result.source.source(),
context: pattern.context
}); // Bug in `loader-utils`, package convert `\\` to `/`, need fix in loader-utils
// eslint-disable-next-line no-param-reassign
result.filename = _path.default.normalize(result.filename);
logger.log(`interpolated template '${filename}' for '${sourceFilename}'`);
}
if (pattern.transformPath) {
logger.log(`transforming '${result.filename}' for '${absoluteFilename}'...`); // eslint-disable-next-line no-param-reassign
result.immutable = false; // eslint-disable-next-line no-param-reassign
result.filename = await pattern.transformPath(result.filename, absoluteFilename);
logger.log(`transformed new '${result.filename}' for '${absoluteFilename}'...`);
} // eslint-disable-next-line no-param-reassign
result.filename = (0, _normalizePath.default)(result.filename); // eslint-disable-next-line consistent-return
return result;
}));
} catch (error) {
compilation.errors.push(error);
return;
}
logger.log(`finished to process a pattern from '${pattern.from}' using '${pattern.context}' context to '${pattern.to}'`); // eslint-disable-next-line consistent-return
return assets;
}

@@ -351,8 +529,10 @@

const logger = compilation.getLogger('copy-webpack-plugin');
const cache = compilation.getCache ? compilation.getCache('CopyWebpackPlugin') : // eslint-disable-next-line no-undefined
undefined;
compilation.hooks.additionalAssets.tapAsync('copy-webpack-plugin', async callback => {
logger.debug('start to adding additional assets');
logger.log('starting to add additional assets...');
let assets;
try {
assets = await Promise.all(this.patterns.map(item => limit(async () => this.runPattern(compiler, compilation, logger, item))));
assets = await Promise.all(this.patterns.map((item, index) => limit(async () => CopyPlugin.runPattern(compiler, compilation, logger, cache, item, index))));
} catch (error) {

@@ -363,3 +543,3 @@ compilation.errors.push(error);

} // Avoid writing assets inside `p-limit`, because it creates concurrency.
// It could potentially lead to an error - "Multiple assets emit different content to the same filename"
// It could potentially lead to an error - 'Multiple assets emit different content to the same filename'

@@ -369,9 +549,8 @@

const {
absoluteFrom,
targetPath,
webpackTo,
data,
absoluteFilename,
sourceFilename,
filename,
source,
force
} = asset;
const source = new RawSource(data); // For old version webpack 4
} = asset; // For old version webpack 4

@@ -382,13 +561,13 @@ /* istanbul ignore if */

// eslint-disable-next-line no-param-reassign
compilation.assets[targetPath] = source;
compilation.assets[filename] = source;
return;
}
const existingAsset = compilation.getAsset(targetPath);
const existingAsset = compilation.getAsset(filename);
if (existingAsset) {
if (force) {
logger.log(`force updating "${webpackTo}" to compilation assets from "${absoluteFrom}"`);
const info = {
copied: true
copied: true,
sourceFilename
};

@@ -400,13 +579,16 @@

compilation.updateAsset(targetPath, source, info);
logger.log(`force updating '${filename}' from '${absoluteFilename}' to compilation assets, because it already exists...`);
compilation.updateAsset(filename, source, info);
logger.log(`force updated '${filename}' from '${absoluteFilename}' to compilation assets, because it already exists`);
return;
}
logger.log(`skipping "${webpackTo}", because it already exists`);
logger.log(`skip adding '${filename}' from '${absoluteFilename}' to compilation assets, because it already exists`);
return;
}
logger.log(`writing "${webpackTo}" to compilation assets from "${absoluteFrom}"`);
logger.log(`writing '${filename}' from '${absoluteFilename}' to compilation assets...`);
const info = {
copied: true
copied: true,
sourceFilename
};

@@ -418,5 +600,6 @@

compilation.emitAsset(targetPath, source, info);
compilation.emitAsset(filename, source, info);
logger.log(`written '${filename}' from '${absoluteFilename}' to compilation assets`);
});
logger.debug('end to adding additional assets');
logger.log('finished to adding additional assets');
callback();

@@ -423,0 +606,0 @@ });

{
"name": "copy-webpack-plugin",
"version": "6.2.1",
"version": "6.3.0",
"description": "Copy files && directories with webpack",

@@ -57,5 +57,5 @@ "license": "MIT",

"devDependencies": {
"@babel/cli": "^7.11.6",
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.11.5",
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@commitlint/cli": "^11.0.0",

@@ -65,14 +65,15 @@ "@commitlint/config-conventional": "^11.0.0",

"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^26.5.2",
"chokidar": "^3.4.2",
"babel-jest": "^26.6.1",
"chokidar": "^3.4.3",
"cross-env": "^7.0.2",
"del": "^6.0.0",
"del-cli": "^3.0.1",
"eslint": "^7.10.0",
"eslint-config-prettier": "^6.12.0",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-import": "^2.22.1",
"file-loader": "^6.1.1",
"husky": "^4.3.0",
"is-gzip": "^2.0.0",
"jest": "^26.5.2",
"lint-staged": "^10.4.0",
"jest": "^26.6.1",
"lint-staged": "^10.4.2",
"memfs": "^3.2.0",

@@ -83,3 +84,3 @@ "mkdirp": "^1.0.4",

"standard-version": "^9.0.0",
"webpack": "^4.44.2"
"webpack": "^5.3.2"
},

@@ -86,0 +87,0 @@ "keywords": [

@@ -51,2 +51,4 @@ <div align="center">

> ℹ️ You can get the original source filename from [Asset Objects](https://webpack.js.org/api/stats/#asset-objects).
## Options

@@ -53,0 +55,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc