hm-react-cli
Version:
Create a Huimei React project by module
247 lines (231 loc) • 11.1 kB
JavaScript
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //html
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //css压缩
const HappyPack = require('happypack'); //多线程运行
const happyThreadPool = HappyPack.ThreadPool({ size: 4 });
const resolve = path.resolve;
const DISTPATH = 'release';
// 以项目的基础目录我基础,解析路径
function baseResolve(...dir) {
return path.join(__dirname, '..', ...dir);
}
/**
* 获取html
*/
const getHTMLWebpackPlugins = (config) => {
const { pageBasePath, pageName } = config;
const template = resolve(pageBasePath, pageName, 'index.html');
return new HtmlWebpackPlugin(getHtmlWebpackPluginParams(template, config));
};
function getHtmlWebpackPluginParams(template, config) {
const { pageName, mode, multiple } = config;
// 生成的HTML文件放到/dist/view目录下
return {
filename: multiple ? 'index.html' : mode === 'prod' ? 'index.html' : pageName + `/index.html`, // 生成的文件放在/dist/view目录下 单文件
// filename: 'index.html', // 生成的文件放在/dist/index.html
template: template, // 模板的位置
title: pageName, // 设置HTML文件中的title值
inject: true, // 插入的script标签放在body后面
hash: true, // 产生hash值
showErrors: true // chunks: ['vendor', name, 'components'],
};
}
module.exports = function (config) {
const { pageBasePath, pageName, inDunshan, mode, multiple } = config;
const entry = {
[pageName]: resolve(pageBasePath, pageName, 'src/main.js')
};
const webpackConfig = {
entry: entry,
output: {
path: inDunshan ? resolve(DISTPATH, 'WebRoot', pageName) : resolve(DISTPATH, pageName), //出口路径
chunkFilename: `js/[name].[hash].js`,
filename: `js/[name].[hash].js`,
publicPath: multiple ? undefined : mode === 'prod' ? undefined : '/' //单文件
},
profile: true,
mode: 'development',
devtool: 'cheap-eval-source-map', //cheap-eval-source-map 是一种比较快捷的map,没有映射列
performance: {
maxEntrypointSize: 250000, //入口文件大小,性能指示
maxAssetSize: 250000, //生成的最大文件
hints: false //依赖过大是否错误提示
},
resolve: {
mainFields: ['main', 'jsnext:main', 'browser'], //npm读取先后方式 jsnext:main 是采用es6模块写法
alias: {
'rc-align': baseResolve('package-modules/rc-align'),
'dom-align': baseResolve('package-modules/dom-align'),
anujs: baseResolve('package-modules/anujs'),
'rc-trigger': baseResolve('package-modules/rc-trigger'),
'rc-calendar': baseResolve('package-modules/rc-calendar'),
'rc-animate': baseResolve('package-modules/rc-animate'),
// 框架相关包替换
react: baseResolve('package-modules/anujs/dist/ReactIE'),
'react-dom': baseResolve('package-modules/anujs/dist/ReactIE'),
redux: baseResolve('package-modules/anujs/lib/ReduxIE'), /// This is mainly for IE6-8, because of the poor performance of the isPlainObject method in the official source code.
'prop-types': baseResolve('package-modules/anujs/lib/ReactPropTypes'),
rematch: baseResolve('package-modules/anujs/dist/Rematch.js'),
antd: baseResolve('node_modules', 'antd'),
'react-redux': baseResolve('node_modules', 'react-redux'),
'react-router': baseResolve('node_modules', 'react-router'),
...config.pages.reduce((pre, pageName) => {
pre['@' + pageName] = resolve(pageBasePath, pageName, 'src');
return pre;
}, {})
}
//配置别名,在项目中可缩减引用路径
},
module: {
// noParse: /node_modules\/(moment|chart\.js)/, //不解析
rules: [
{
test: /\.js$/,
// exclude: [],
use: [
{
loader: baseResolve('node_modules', 'babel-loader'),
options: {
assumptions: {
constantReexports: true
},
plugins: [
[
baseResolve('node_modules', '@babel/plugin-proposal-decorators'),
{
legacy: true
}
],
[
baseResolve('node_modules', '@babel/plugin-proposal-class-properties'),
{
loose: false
}
],
[
baseResolve('node_modules', 'babel-plugin-import/lib/index.js'),
{
libraryName: 'antd',
style: true // or 'css'
}
],
[
baseResolve('node_modules', '@babel/plugin-proposal-private-methods'),
{
loose: false
}
],
[
baseResolve(
'node_modules',
'@babel/plugin-proposal-private-property-in-object'
),
{
loose: false
}
]
],
presets: [
[
baseResolve('node_modules', '@babel/preset-env'),
{
// "useBuiltIns": "entry",
// "corejs": "3",
// "loose": true,
loose: true,
modules: false,
targets: {
browsers: ['ie >= 6', '> 0.2%']
}
}
],
[
baseResolve('node_modules', '@babel/preset-react'),
{
loose: true
}
]
]
}
}
]
},
{
test: /\.css$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{
loader: baseResolve('node_modules', 'css-loader')
// options: {
// minimize: minimize[dev], //压缩
// sourceMap: minimize[dev]
// }
}
]
},
{
test: /\.(png|jpg|gif|jpeg|ttf|svg)$/,
// exclude: /(node_modules|bower_components)/,
// include: [resolve(__dirname, 'src/assets/images'), resolve(__dirname, 'src/assets/images')],
use: [
{
loader: baseResolve('node_modules', 'url-loader'), //limit 图片大小的衡量,进行base64处理
options: {
esModule: false, // 这里设置为false
limit: 8,
name: 'images/[name].[ext]',
publicPath: '/assets/'
}
},
{
loader: baseResolve('node_modules', 'file-loader'),
options: {
// 配置参数
// 这种配置语法叫做:占位符
name: '[path][name].[ext]' // 使用图片的名字,并使用图片的后缀
}
}
]
},
{
test: /\.less/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{
loader: baseResolve('node_modules', 'css-loader'),
options: {
// minimize: minimize[dev], //压缩
// sourceMap: minimize[dev]
}
},
{
loader: baseResolve('node_modules', 'less-loader'),
options: {
javascriptEnabled: true
}
}
]
}
]
},
target: 'web',
plugins: [
getHTMLWebpackPlugins(config),
new MiniCssExtractPlugin({
filename: 'css/[name].[hash].css',
chunkFilename: 'css/[chunkhash].css'
}),
new HappyPack({
//多线程运行 默认是电脑核数-1
id: 'babel', //对于loaders id
loaders: [
baseResolve('node_modules', 'cache-loader'),
baseResolve('node_modules', 'babel-loader?cacheDirectory')
], //是用babel-loader解析
threadPool: happyThreadPool,
verboseWhenProfiling: false //显示信息
})
]
};
return webpackConfig;
};