zyk-cli
Version:
生成 React 或 Vue初始代码,生成 webpack 配置,以及配置 webpack 优化项
296 lines (277 loc) • 7.32 kB
text/typescript
import { write } from "utils/file";
import Package from "utils/package";
import Options from "utils/options";
const pkg = Package.getInstance();
const opts = Options.getInstance();
const initBabelConfig = (
type: string | undefined,
isCompatibleDecorator: boolean | undefined
) => {
const babelConfig = `const isDev = process.env.NODE_ENV === "development";
module.exports = {
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3,
}
],${
type === "React"
? `
"@babel/preset-react",
"@babel/preset-typescript",`
: `
[
"@babel/preset-typescript",
{
allExtensions: true,
},
],`
}
],
plugins: [${
isCompatibleDecorator
? `
["@babel/plugin-proposal-decorators", { legacy: true }],`
: ""
}${
type === "React"
? `
isDev && require.resolve("react-refresh/babel"),`
: ``
}
].filter(Boolean),
};
`;
const browserslistrc = `IE 9 # 兼容IE 9
chrome 35 # 兼容chrome 35
`;
write("babel.config.js", babelConfig);
write(".browserslistrc", browserslistrc);
};
export default () => {
const { devDependencies } = pkg.get();
const {
type,
isCompatibleCss3,
isCompatibleLowBrowser,
isCompatibleDecorator,
optimizationItems,
} = opts.getAll();
let newDevDependencies = {
...devDependencies,
"@babel/core": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
chalk: "^4.1.2",
"copy-webpack-plugin": "^11.0.0",
"babel-loader": "^9.1.0",
"css-loader": "^6.7.2",
"html-webpack-plugin": "^5.5.0",
less: "^4.1.3",
"less-loader": "^11.1.0",
"progress-bar-webpack-plugin": "^2.1.0",
"style-loader": "^3.3.1",
"webpack-cli": "^5.0.0",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0",
"cross-env": "^7.0.3",
};
if (type === "React") {
newDevDependencies = {
...newDevDependencies,
"@babel/preset-react": "^7.18.6",
};
} else if (type === "Vue") {
newDevDependencies = {
...newDevDependencies,
"vue-loader": "^17.0.1",
};
}
if (isCompatibleCss3) {
newDevDependencies = {
...newDevDependencies,
"postcss-loader": "^7.0.1",
autoprefixer: "^10.4.13",
};
}
if (isCompatibleLowBrowser) {
newDevDependencies = {
...newDevDependencies,
"@babel/preset-env": "^7.20.2",
"core-js": "^3.26.1",
};
initBabelConfig(type, isCompatibleDecorator);
}
if (isCompatibleDecorator) {
newDevDependencies = {
...newDevDependencies,
"@babel/plugin-proposal-decorators": "^7.20.2",
};
}
if (optimizationItems?.includes("isOpenThreadLoader")) {
newDevDependencies = {
...newDevDependencies,
"thread-loader": "^3.0.4",
};
}
if (optimizationItems?.includes("isPulloutCssFile")) {
newDevDependencies = {
...newDevDependencies,
"mini-css-extract-plugin": "^2.7.0",
};
}
const initConfig = `const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const chalk = require("chalk");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
${
optimizationItems?.includes("isPulloutCssFile")
? `const MiniCssExtractPlugin = require("mini-css-extract-plugin");`
: ""
}
${type === "Vue" ? 'const { VueLoaderPlugin } = require("vue-loader");' : ""}
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
entry: path.join(__dirname, ${
type === "React" ? `"../src/index.tsx"` : `"../src/main.ts"`
}),
output: {
filename: 'static/js/[name].[contenthash:8].js',
path: path.join(__dirname, '../dist'),
clean: true,
publicPath: '/',
},
module: {
rules: [${
type === "React"
? `
{
test: /.(ts|tsx)$/,${
isCompatibleLowBrowser
? `
use: [${
optimizationItems?.includes("isOpenThreadLoader")
? `"thread-loader",`
: ""
}"babel-loader"],`
: `
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-react',
'@babel/preset-typescript',
]
}
},`
}
include: [path.resolve(__dirname, "../src")],
},`
: `
{
test: /.(ts|tsx)$/,
use: 'babel-loader',
},
{
test: /\.vue$/,
use: ['thread-loader', 'vue-loader'],
include: [path.resolve(__dirname, "../src")],
},`
}
{
test: /.(css|less)$/,
use: [${
optimizationItems?.includes("isPulloutCssFile")
? `
isDev ? "style-loader" : MiniCssExtractPlugin.loader`
: `
"style-loader"`
},
"css-loader",${
isCompatibleCss3
? `
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["autoprefixer"],
},
},
},`
: ""
}
"less-loader",
],
include: [path.resolve(__dirname, "../src")],
},
{
test: /.(png|jpg|jpeg|gif|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024,
},
},
generator: {
filename: "static/images/[name].[contenthash:8][ext]",
},
},
{
test: /.(woff2?|eot|ttf|otf)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024,
},
},
generator: {
filename: "static/fonts/[name].[contenthash:8][ext]",
},
},
{
test: /.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024,
},
},
generator: {
filename: "static/media/[name].[contenthash:8][ext]",
},
},
],
},
plugins: [
new ProgressBarPlugin({
format: \`:msg [:bar] \${chalk.green.bold(":percent")} (:elapsed s)\`,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html'),
inject: true,
}),
new webpack.DefinePlugin({
'process.env.BASE_ENV': JSON.stringify(process.env.BASE_ENV),
}),
${type === "Vue" ? "new VueLoaderPlugin()," : ""}
],
resolve: {
extensions: [".js", ".tsx", ".ts"${type === "Vue" ? ', ".vue"' : ""}],
alias: { "@": path.join(__dirname, "../src") },
modules: [path.resolve(__dirname, "../node_modules")],
},${
optimizationItems?.includes("isOpenStorageCache")
? `
cache: {
type: "filesystem",
},`
: ``
}
};
`;
pkg.set("devDependencies", newDevDependencies);
write("build/webpack.base.js", initConfig);
};