dn-middleware-webpack5
Version:
--- group: middleware name: webpack5 title: Webpack5 ---
229 lines (188 loc) • 13.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _resolve = _interopRequireDefault(require("resolve"));
var path = _interopRequireWildcard(require("path"));
var _webpack = require("webpack");
var _ModuleNotFoundPlugin = _interopRequireDefault(require("react-dev-utils/ModuleNotFoundPlugin"));
var _ForkTsCheckerWebpackPlugin = _interopRequireDefault(require("react-dev-utils/ForkTsCheckerWebpackPlugin"));
var _typescriptFormatter = _interopRequireDefault(require("react-dev-utils/typescriptFormatter"));
var _esbuildLoader = require("esbuild-loader");
var _miniCssExtractPlugin = _interopRequireDefault(require("mini-css-extract-plugin"));
var _webpackBundleAnalyzer = require("webpack-bundle-analyzer");
var _reactRefreshWebpackPlugin = _interopRequireDefault(require("@pmmmwh/react-refresh-webpack-plugin"));
var _webpackbar = _interopRequireDefault(require("webpackbar"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// import InterpolateHtmlPlugin from "react-dev-utils/InterpolateHtmlPlugin";
// import WatchMissingNodeModulesPlugin from "react-dev-utils/WatchMissingNodeModulesPlugin";
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
const VModulePlugin = require("vmodule-webpack-plugin"); // import InlineChunkHtmlPlugin from "react-dev-utils/InlineChunkHtmlPlugin";
// import getCacheIdentifier from "react-dev-utils/getCacheIdentifier";
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); // Generate webpack plugins
const getPlugins = (options, ctx) => {
var _options$folders$styl, _options$folders2, _options$folders$styl2, _options$folders3, _options$esbuild, _options$esbuild2, _options$config, _options$config2, _options$config3, _options$config4, _options$config5;
const plugins = []; // false or empty array
// if (options?.template?.length) {
// HTMLWebpackPlugin
// Generates an `index.html` file with the <script> injected.
options.entry.forEach(({
name
}) => {
var _options$template$fin, _options$template, _options$template$fin2, _options$template2, _options$folders$html, _options$folders, _options$common;
const template = (_options$template$fin = (_options$template = options.template) === null || _options$template === void 0 ? void 0 : (_options$template$fin2 = _options$template.find) === null || _options$template$fin2 === void 0 ? void 0 : _options$template$fin2.call(_options$template, temp => temp.name === name)) !== null && _options$template$fin !== void 0 ? _options$template$fin : (_options$template2 = options.template) === null || _options$template2 === void 0 ? void 0 : _options$template2[0];
if (!template) return;
const minifyOption = ctx.isEnvProduction // auto minify when production mode
? {
// https://github.com/DanielRuf/html-minifier-terser
// Strip HTML comments
removeComments: true,
// Collapse white space that contributes to text nodes in a document tree
collapseWhitespace: true,
// Remove attributes when value matches default.
removeRedundantAttributes: true,
// Replaces the doctype with the short (HTML5) doctype
useShortDoctype: true,
// Remove all attributes with whitespace-only values
removeEmptyAttributes: true,
// Remove type="text/css" from style and link tags. Other type attribute values are left intact
removeStyleLinkTypeAttributes: true,
// Keep the trailing slash on singleton elements
keepClosingSlash: true,
// Minify JavaScript in script elements and event attributes (uses Terser)
minifyJS: true,
// Minify CSS in style elements and style attributes (uses clean-css)
minifyCSS: true,
// Minify URLs in various attributes (uses relateurl)
minifyURLs: true
} : false;
plugins.push(new HtmlWebpackPlugin({
inject: true,
filename: path.join((_options$folders$html = options === null || options === void 0 ? void 0 : (_options$folders = options.folders) === null || _options$folders === void 0 ? void 0 : _options$folders.html) !== null && _options$folders$html !== void 0 ? _options$folders$html : "", `${name}.html`),
template: template.file,
chunks: [options === null || options === void 0 ? void 0 : (_options$common = options.common) === null || _options$common === void 0 ? void 0 : _options$common.name, name].filter(Boolean),
minify: minifyOption
}));
}); // }
// InlineChunkHtmlPlugin
// Inlines the webpack runtime script. This script is too small to warrant a network request.
// https://github.com/facebook/create-react-app/tree/master/packages/react-dev-utils#new-inlinechunkhtmlpluginhtmlwebpackplugin-htmlwebpackplugin-tests-regex
// ctx.isEnvProduction && plugins.push(new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]) as any);
// InterpolateHtmlPlugin
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// It will be an empty string unless you specify "homepage" in `package.json`, in which case it will be the pathname of that URL.
// https://github.com/facebook/create-react-app/tree/master/packages/react-dev-utils#new-interpolatehtmlpluginhtmlwebpackplugin-htmlwebpackplugin-replacements-keystring-string
// plugins.push(
// new InterpolateHtmlPlugin(HtmlWebpackPlugin, {
// TODO: add some envs
// }) as any,
// );
// ModuleNotFoundPlugin
// This gives some necessary context to module not found errors, such as the requesting resource.
plugins.push(new _ModuleNotFoundPlugin.default(options.cwd)); // DefinePlugin
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV is set to production during a production build.
// Otherwise React will be compiled in the very slow development mode.
plugins.push(new _webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify(options.env) // production
}
})); // CaseSensitivePathsPlugin
// Watcher doesn't work well if you mistype casing in a path so we use a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240
// https://github.com/Urthen/case-sensitive-paths-webpack-plugin
ctx.isEnvDevelopment && plugins.push(new CaseSensitivePathsPlugin()); // MiniCssExtractPlugin
// Options similar to the same options in webpackOptions.output both options are optional
!ctx.injectCSS && plugins.push(new _miniCssExtractPlugin.default({
filename: path.join((_options$folders$styl = options === null || options === void 0 ? void 0 : (_options$folders2 = options.folders) === null || _options$folders2 === void 0 ? void 0 : _options$folders2.style) !== null && _options$folders$styl !== void 0 ? _options$folders$styl : "", "[name].css"),
chunkFilename: path.join((_options$folders$styl2 = options === null || options === void 0 ? void 0 : (_options$folders3 = options.folders) === null || _options$folders3 === void 0 ? void 0 : _options$folders3.style) !== null && _options$folders$styl2 !== void 0 ? _options$folders$styl2 : "", "[name].[contenthash:8].chunk.css")
}));
if (options.hot) {
// This is necessary to emit hot updates (CSS and Fast Refresh):
// https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/232
plugins.push(new _reactRefreshWebpackPlugin.default({
// include: /\.(js|jsx|ts|tsx|flow)$/i,
overlay: {
// entry: require.resolve("react-dev-utils/webpackHotDevClient"),
sockIntegration: "whm" // entry: require.resolve('@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry'),
// module: require.resolve('@pmmmwh/react-refresh-webpack-plugin/overlay'),
// TODO: This is just a stub module. Clean this up if possible.
// module: require.resolve('./hotRefreshOverlayModuleStub'),
}
}));
plugins.push(new _webpack.HotModuleReplacementPlugin());
}
if (options !== null && options !== void 0 && (_options$esbuild = options.esbuild) !== null && _options$esbuild !== void 0 && _options$esbuild.minify || options !== null && options !== void 0 && (_options$esbuild2 = options.esbuild) !== null && _options$esbuild2 !== void 0 && _options$esbuild2.loader) {
plugins.push(new _esbuildLoader.ESBuildPlugin());
}
const clearConsoleReporter = {
start() {
const allowScrollBack = true;
process.stdout.write(allowScrollBack ? "\x1B[H\x1B[2J" : "\x1B[2J\x1B[3J\x1B[H\x1Bc");
}
};
plugins.push(new _webpackbar.default({
reporters: [options.watch ? clearConsoleReporter : null, "fancy", options.analysis || ctx.isEnvProduction ? "stats" : null].filter(Boolean)
})); // webpack.IgnorePlugin
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// checkContext was removed from IgnorePlugin in webpack5.
// now IgnorePlugin must now be passed only one argument that can be an object, string or function.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
// new IgnorePlugin({
// resourceRegExp: /^\.\/locale$/,
// contextRegExp: /moment$/
// });
// BundleAnalyzerPlugin
// https://github.com/webpack-contrib/webpack-bundle-analyzer
const analysisOptions = options.analysis === true ? {} : options.analysis;
options.analysis && plugins.push(new _webpackBundleAnalyzer.BundleAnalyzerPlugin(analysisOptions)); // ForkTsCheckerWebpackPlugin
// TypeScript type checking
ctx.useTypeScript && plugins.push(new _ForkTsCheckerWebpackPlugin.default({
typescript: _resolve.default.sync("typescript", {
basedir: path.join(options.cwd, "node_modules")
}),
async: ctx.isEnvDevelopment,
checkSyntacticErrors: true,
tsconfig: path.join(options.cwd, "tsconfig.json"),
reportFiles: [// This one is specifically to match during tests, as micromatch doesn't match
"../**/src/**/*.{ts,tsx}", "**/src/**/*.{ts,tsx}", "!**/src/**/__tests__/**", "!**/src/**/?(*.)(spec|test).*", "!**/src/setupProxy.*", "!**/src/setupTests.*"],
silent: true,
// The formatter is invoked directly in WebpackDevServerUtils during development
formatter: ctx.isEnvProduction ? _typescriptFormatter.default : undefined
})); // https://webpack.docschina.org/concepts/module-federation/
options.moduleFederation && plugins.push(new ModuleFederationPlugin({
// name: "app_one_remote",
// remotes: {
// app_two: "app_two_remote",
// app_three: "app_three_remote"
// },
// exposes: {
// AppContainer: "./src/App"
// },
shared: ["react", "react-dom"],
...options.moduleFederation
})); // $config Plugin
const configPath = path.resolve(options.cwd, options === null || options === void 0 ? void 0 : (_options$config = options.config) === null || _options$config === void 0 ? void 0 : _options$config.path); // @ts-ignore
ctx.utils.confman.env = options === null || options === void 0 ? void 0 : (_options$config2 = options.config) === null || _options$config2 === void 0 ? void 0 : _options$config2.env;
ctx.$config = ctx.utils.confman.load(configPath) || (options === null || options === void 0 ? void 0 : (_options$config3 = options.config) === null || _options$config3 === void 0 ? void 0 : _options$config3.content);
ctx.$config && plugins.push(new VModulePlugin.VModulePlugin({
env: options === null || options === void 0 ? void 0 : (_options$config4 = options.config) === null || _options$config4 === void 0 ? void 0 : _options$config4.env,
name: options === null || options === void 0 ? void 0 : (_options$config5 = options.config) === null || _options$config5 === void 0 ? void 0 : _options$config5.name,
content: ctx.$config,
watch: [configPath, `${configPath}.*`, `${configPath}/**/*.*`]
}));
return plugins;
};
var _default = getPlugins;
exports.default = _default;
module.exports = exports.default;