nx/packages/next/src/utils/create-copy-plugin.ts

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,
},
};
}),
});
}