1. npm的配置
package.json
run-p 并行执行后面的命令
npm run 执行单个命令,如需执行多个,需要用&&,且是串行执行
webpack --config=config/webpack.config.js --env.production
打包命令 --config 打包配置文件 --env 传入环境变量 env.production = true
webpack-dev-server --config=config/webpack.config.js --open --env.development
启动本地服务
"scripts": {
"dev": "run-p build-dev server",
"build": "npm run build-base && npm run css2json &&npm run push-apach",
"build-base": "webpack --config=config/webpack.config.js --env.production",
"css2json": "node ./build_tool/css2json",
"build-dev": "webpack --config=config/webpack.config.js --env.development --watch",
"--server": "webpack-dev-server --content-base ./dist --open",
"server": "webpack-dev-server --config=config/webpack.config.js --open --env.development",
"push-aws": "node ./build_tool/aws_s3 js",
"clear-cdn": "node ./build_tool/purge.js",
"deploy": "run-p build push-aws clear-cdn",
"push-apach": "node ./build_tool/push_apach js"
},
2. webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
// @see https://github.com/jaywcjlove/mocker-api
const ApiMocker = require('mocker-api');
const Webpack = require('webpack');
const ROOT = path.resolve(__dirname, '../');
const DIST_DIR = path.join(ROOT, 'dist');
const CDN = 'http://xxx.xxx.xxx';
module.exports = (env) => {
const config = {
entry: './src/index.js', // 入口
output: {
filename: 'comment-v2.js',
// filename: env.production ? '[name].[hash:8].js' : '[name].js',
// 这个路径必须是绝对路径
path: path.join(DIST_DIR, 'static'),
publicPath: env.production ? `${CDN}/static` : '/static'
},
resolve: {
alias: {
'@': path.join(ROOT, 'src')
}
}, // 配置解析
module: { // 模块配置
rules: [
{
test: /\.scss$/,
use: [
env.development ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
],
exclude: /node_modules/
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/
},
{
test: /\.tpl$/,
loader: "art-template-loader",
options: {
// art-template options (if necessary)
// @see https://github.com/aui/art-template
}
},{
test: /\.(png|jpg|gif|svg)$/,
use: [{
loader: 'url-loader',
options: { // 这里的options选项参数可以定义多大的图片转换为base64
limit: 500, // 表示小于0.5kb的图片转为base64,大于0.5kb的是路径
name: '[name].[ext]',
publicPath: env.production ? `${CDN}/imgs` : '/imgs',
outputPath: '../imgs' //path.join(ROOT, './dist/imgs') //定义输出的图片文件夹
}
}]
}
]
},
plugins: [ // 插件的配置
new Webpack.DefinePlugin({
'$_WEBPACK_API_HOST_': env.production ? '"https://xxx"' : '"http://yyy:8080"'
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css'
// filename: env.production ? '[name].[hash:8].css' : '[name].css',
// chunkFilename: env.production ? '[id].[hash:8].css' : '[id].css'
}),
new Webpack.HotModuleReplacementPlugin()
],
mode: env.production ? 'production' : 'development', // 可以更改模式
devServer: { // 开发服务器
contentBase: DIST_DIR,
port: 8088,
compress: false, // 服务器压缩
open: true, // 自动打开浏览器
hot:true,//热更新
// hotOnly:true
before(app){
ApiMocker(app, path.join(ROOT,'./mock/server.js'), {
// proxy: {
// '/comments/*': 'http://172.xxx.xx.x:8080/'
// },
// changeHost: true
});
}
}
}
// production
if (env.production) {
config.plugins = config.plugins.concat([
new CleanWebpackPlugin(['dist'], {
root: ROOT
}),
// new UglifyWebpackPlugin(),
// new OptimizeCSSAssetsPlugin({})
]);
config.module.rules = config.module.rules.concat([{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}])
}else if(env.development){
config.plugins = config.plugins.concat([
new HtmlWebpackPlugin({
template: path.join(ROOT, 'test/index.html'), //是要打包的html模版路径和文件名称。
filename: path.join(DIST_DIR, 'index.html')
})
])
}
return config;
}
2.1 loader: "art-template-loader", 解析为HTML
2.2 loader: 'url-loader', url-loader 将小于指定大小的图片文件(或字体文件)转换为 Data URL,减少 HTTP 请求
2.3 new Webpack.DefinePlugin(optioins), 创建全局变量,可在代码中使用
2.4 loader 中的 style-loader
替换为 MiniCssExtractPlugin.loader
。这会将 CSS 提取到单独的文件中,而不是将 CSS 注入到 JS bundle 里
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css'
// filename: env.production ? '[name].[hash:8].css' : '[name].css',
// chunkFilename: env.production ? '[id].[hash:8].css' : '[id].css'
}),
2.4 new Webpack.HotModuleReplacementPlugin() 热更新
2.5 自定义模拟网络请求ApiMocker
before
函数是在Webpack的开发服务器(devServer
)启动并开始服务之前执行的一个钩子函数ApiMocker设置对API请求的模拟响应
before(app){
ApiMocker(app, path.join(ROOT,'./mock/server.js'), {
// proxy: {
// '/comments/*': '127.0.0.1:8088'
// },
// changeHost: true
});
}
./mock/server.js
const fs = require('fs');
function returFromFile() {
return (req, res) => {
let data = fs.readFileSync(`mock/data/${req.params.filename}.json`).toString();
if(req.query.callback){
data = `${req.query.callback}(${data})`;
}
return res.send(data);
};
}
// @see https://github.com/jaywcjlove/mocker-api
const proxy = {
'GET /api/:filename': returFromFile(),
'POST /api/:filename': returFromFile()
};
module.exports = proxy;