2023-03-01 16:29:42 +08:00

127 lines
4.5 KiB
JavaScript

import { join } from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import { buildSwcOptions } from './swcOptions';
const DEFAULT_EXCLUDE_NODE_MODULES = [
'vue',
'vuex',
'vue-router',
'core-js',
'echarts',
'@babel/runtime',
'lodash-es',
'webpack-dev-server',
'ansi-html',
'html-entities',
];
function genTranspileDepRegex(exclude) {
exclude = exclude.concat(DEFAULT_EXCLUDE_NODE_MODULES);
const deps = exclude.map((dep) => {
if (typeof dep === 'string') {
const depPath = join('node_modules', dep, '/');
return /^win/.test(require('os').platform()) ? depPath.replace(/\\/g, '\\\\') : depPath;
}
if (dep instanceof RegExp) {
return dep.source;
}
throw new Error('exclude only accepts an array of string or regular expressions');
});
return deps.length ? new RegExp(deps.join('|')) : null;
}
export default (api) => {
api.describe({
key: 'swc',
config: {
schema(joi) {
return joi.object({
loader: joi.object().description('more swc options see https://github.com/swc-project/swc-loader'),
});
},
},
});
if (api.builder.name === 'vite') {
// vite 不需要处理
} else {
api.chainWebpack((webpackConfig, { targets, env }) => {
const isProd = env === 'production';
const config = api.config;
//清除babel配置
webpackConfig.module.rules.delete('js');
webpackConfig.module
.rule('js')
.test(/\.(js|mjs)$/)
// Don't transpile node_modules
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, false));
webpackConfig.module
.rule('jsx')
.test(/\.jsx$/)
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, true, false));
webpackConfig.module
.rule('ts')
.test(/\.ts$/)
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, true));
webpackConfig.module
.rule('tsx')
.test(/\.tsx$/)
.exclude.add(/node_modules/)
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, true, true));
// 为了避免第三方依赖包编译不充分导致线上问题,默认对 node_modules 也进行全编译,只在生产构建的时候进行
if (isProd) {
webpackConfig.module.rules.delete('js-in-node_modules');
// const cjsReg = [/css-loader/, /vue-loader/].concat(config.swcLoader?.cjsPkg || []);
const transpileDepRegex = genTranspileDepRegex(config.nodeModulesTransform.exclude);
webpackConfig.module
.rule('js-in-node_modules')
.test(/\.(js|mjs)$/)
.include.add(/node_modules/)
.end()
.exclude.add((filepath) => {
if (transpileDepRegex && transpileDepRegex.test(filepath)) {
return true;
}
return false;
})
.end()
.use('swc-loader')
.loader(require.resolve('swc-loader'))
.options(buildSwcOptions(targets, config, false, false));
const swcOptions = buildSwcOptions(targets, config, false, false, true);
webpackConfig.optimization.minimizer('css').tap((args) => [...args, { minify: CssMinimizerPlugin.swcMinify }]);
webpackConfig.optimization
.minimizer('terser')
.tap((args) => [...args, { terserOptions: swcOptions.jsc?.minify, minify: TerserPlugin.swcMinify }]);
}
return webpackConfig;
});
}
};