84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
|
|
import { normalizePath } from 'nx/src/utils/path';
|
|
import { basename, dirname, join, relative, resolve } from 'path';
|
|
import { statSync } from 'fs';
|
|
|
|
interface AssetGlobPattern {
|
|
glob: string;
|
|
input: string;
|
|
output: string;
|
|
ignore?: string[];
|
|
}
|
|
|
|
function normalizeAssets(
|
|
assets: any[],
|
|
root: string,
|
|
sourceRoot: string
|
|
): AssetGlobPattern[] {
|
|
return assets.map((asset) => {
|
|
if (typeof asset === 'string') {
|
|
const assetPath = normalizePath(asset);
|
|
const resolvedAssetPath = resolve(root, assetPath);
|
|
const resolvedSourceRoot = resolve(root, sourceRoot);
|
|
|
|
if (!resolvedAssetPath.startsWith(resolvedSourceRoot)) {
|
|
throw new Error(
|
|
`The ${resolvedAssetPath} asset path must start with the project source root: ${sourceRoot}`
|
|
);
|
|
}
|
|
|
|
const isDirectory = statSync(resolvedAssetPath).isDirectory();
|
|
const input = isDirectory
|
|
? resolvedAssetPath
|
|
: dirname(resolvedAssetPath);
|
|
const output = relative(resolvedSourceRoot, resolve(root, input));
|
|
const glob = isDirectory ? '**/*' : basename(resolvedAssetPath);
|
|
return {
|
|
input,
|
|
output,
|
|
glob,
|
|
};
|
|
} else {
|
|
if (asset.output.startsWith('..')) {
|
|
throw new Error(
|
|
'An asset cannot be written to a location outside of the output path.'
|
|
);
|
|
}
|
|
|
|
const assetPath = normalizePath(asset.input);
|
|
const resolvedAssetPath = resolve(root, assetPath);
|
|
return {
|
|
...asset,
|
|
input: resolvedAssetPath,
|
|
// Now we remove starting slash to make Webpack place it from the output root.
|
|
output: asset.output.replace(/^\//, ''),
|
|
};
|
|
}
|
|
});
|
|
}
|
|
|
|
export function createCopyPlugin(
|
|
assets: any[],
|
|
root: string,
|
|
sourceRoot: string
|
|
) {
|
|
return new CopyWebpackPlugin({
|
|
patterns: normalizeAssets(assets, root, sourceRoot).map((asset) => {
|
|
return {
|
|
context: asset.input,
|
|
to: join('../public', asset.output),
|
|
from: asset.glob,
|
|
globOptions: {
|
|
ignore: [
|
|
'.gitkeep',
|
|
'**/.DS_Store',
|
|
'**/Thumbs.db',
|
|
...(asset.ignore ?? []),
|
|
],
|
|
dot: true,
|
|
},
|
|
};
|
|
}),
|
|
});
|
|
}
|