hm-react-cli
Version:
Create a Huimei React project by module
137 lines (117 loc) • 4.76 kB
JavaScript
const os = require('os');
const path = require('path');
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const WebpackDevServer = require('webpack-dev-server');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const webpackBase = require('./webpack.config.base');
const getUsablePort = require('./utils/getUsablePort'); //多线程运行
const resolve = path.resolve;
const configPort = 8000;
// 配置
// 合并配置文件
module.exports = async function main(config) {
const { pageBasePath, pages = [], dev = {} } = config;
const PORT = await getUsablePort(configPort);
const assetsDir = pages.map((pageName) => resolve(pageBasePath, pageName) + '/');
const otherNote = configPort == PORT ? '' : yellow(`warning:检测到${configPort}端口被占用,已切换到${PORT}端口\n`);
const webpackConfig = pages.map((pageName) =>
merge(webpackBase({ ...config, pageName, multiple: pages.length > 1 }), {
plugins: [
// DefinePlugin 允许创建一个在编译时可以配置的全局常量,可以在JS文件中根据这些定义的变量来定义不同的行为
new webpack.DefinePlugin({
'process.env': resolve(pageBasePath, './dev.env')
}),
new ProgressBarPlugin({
width: 100,
clear: true
}),
new FriendlyErrorsWebpackPlugin({
compilationSuccessInfo: {
messages: [
`${blue('Server listening on:')}
> Local: ${blue('http://localhost:' + PORT + '/' + pages[0])}/
> Network: ${blue('http://' + getIpAddress() + ':' + PORT + '/' + pages[0])}/
${otherNote}${cyan('The current page module is:')} [ ${blue(pages.join('、'))} ] }
`
]
},
clearConsole: true
})
],
optimization: {
splitChunks: {
chunks: 'async',
minSize: 200,
// minRemainingSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
}
}
})
);
const configAssetsDir = [].concat(config.assetsDir).filter((el) => Boolean(el));
const compiler = webpack(webpackConfig);
const devServer = {
contentBase: [
...(configAssetsDir.length
? configAssetsDir.map((dir) => resolve(process.cwd(), dir))
: resolve(pageBasePath)),
...assetsDir,
],
compress: true, //开发服务器是否启动gzip等压缩
port: PORT, //端口
host: '0.0.0.0',
quiet: true,
useLocalIp: true,
// hot: true,
// historyApiFallback: true, //不会出现404页面,避免找不到
open: typeof dev.open !== 'undefined' ? dev.open : true, // 不自动打开浏览器
openPage: typeof dev.openPage !== 'undefined' ? dev.openPage : pages.map((page) => page + '/'),
// publicPath: '/',
// 错误、警告展示设置
overlay: dev.overlay || { errors: true, warnings: false },
// 代理
proxy: dev.proxy || void 0
};
const server = new WebpackDevServer(compiler, devServer);
server.listen(PORT);
};
function blue(str) {
return '\x1b[1m\x1b[34m' + str + '\x1b[39m\x1b[22m';
}
function cyan(str) {
return '\x1B[36m' + str + '\x1B[0m';
}
function yellow(str) {
return '\x1B[33m' + str + '\x1B[0m';
}
function getIpAddress() {
var interfaces = os.networkInterfaces();
for (var dev in interfaces) {
let iface = interfaces[dev];
for (let i = 0; i < iface.length; i++) {
let { family, address, internal } = iface[i];
if (family === 'IPv4' && address !== '127.0.0.1' && !internal) {
return address;
}
}
}
}