代码已上传至github github代码地址:https://github.com/Miofly/mio.git
webpack.common.js
以下是公共配置,生产与开发环境打包时都会经过下面的配置
代码语言:javascript复制const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const merge = require('webpack-merge')
const devConfig = require('./webpack.dev')
const prodConfig = require('./webpack.prod')
function resolve(dir) {
return path.join(__dirname, '../../../../', dir)
}
const commonConfig = { // 配置好后 npx webpack
entry: { // 上面是简写
// lodash: './src/lodash.js',
// myVue: './src/index.js',
sub: './src/main.js'
},
output: { // 输出到bundle/bundle.js
// publicPath: 'http://192.168.3.99:8888/mio/src/html/', // 类似base_url
filename: '[name].js', // 打包文件的文件名 这样entry可以配置两个入口js 入口文件走这里
chunkFilename: '[name].chunk.js', // index.js里又引入的js走这里
// path: path.resolve(__dirname, './dist') // __dirname指webpack.config.js文件的当前路径
},
resolve: {
// extensions: ['.js', '.vue', '.json'], // 可以导入的时候忽略的拓展名范围
extensions: ['.js', '.json', '.vue', '.scss', '.css'], // 省略文件名后缀
alias: {
'@': resolve('src'),
zj: resolve('src/components'),
mioJs: resolve('src/common/js'),
json: resolve('src/static/mockJson'),
}
},
module: { // loader的顺序从下到上,从右到左
rules: [
{
test: /.js$/,
exclude: /node_modules/, // 排除在外
loader: 'babel-loader', // 使用babel-loader把es6语法转成es5语法
options: {
presets: [['@babel/preset-env', {
// targets: {
// chrome: '67' // 此版本中的浏览器不需要转es5语法
// },
// 弥补低版本浏览器不支持转es5语法
// 使用下面这个属性,不需要 import '@babel/polyfill'
// 他会根据使用es6的情况只代码使用到的es6语法
// useBuiltIns: 'usage',
// corejs: 3
}]]
}
},
{
test: /.(jpg|png|gif)$/,
use: { // 把图片变成base64,适合小图片
loader: 'url-loader', // npm install url-loader -D
options: {
// placeholder 占位符 [ext]后缀
name: '[name]_[hash].[ext]', // 使打包出的图片文件名 后缀和以前一样
outputPath: 'images/', // 图片打包到images/文件夹
limit: 2048 // <2kb生成base64 >2kb会在images/生成文件
}
}
},
]
},
plugins: [
new HtmlWebpackPlugin({ // 打包后自动生成一个HTML文件,并把打包生成的js自动引入到这个html文件中
template: './src/index.html' // 以index.html为模板打包
}),
new CleanWebpackPlugin(), // 清除之前打包的文件
],
optimization: { // treeshaking在开发环境下未使用的js仍然存在,但提示只使用了某一个
usedExports: true,
// runtimeChunk: { // 老版本的webpack会由于manifest造成因为没改代码
// // 也会让contenthash改变, 配置上runtimeChunk会把manifest造成的
// // 不同js代码单独抽离出来(抽离的文件runtime.js)
// name: 'runtime'
// },
// // production下不需要 // 在mode: 'development'配置Tree Shaking
// splitChunks: { // 默认配置即可 代码分割
// chunks: 'all',
// cacheGroups: { // 缓存组
// vendors: { // 如果代码是node_modules里的则打包成vendors.js
// test: /[\/]node_modules[\/]/,
// priority: -10, // 优先级
// // filename: 'vendor11s.js'
// name: 'vendor'
// },
// }
// }
/* splitChunks: { // 默认配置
chunks: "all", // 只对异步代码生效 all同步异步都分割 initial同步(配合cacheGroups使用)
minSize: 30000, // >30kb就做代码分割
minChunks: 1, // 当一个模块用了多少次才进行代码分割
maxAsyncRequests: 5, // 同时加载的模块数
maxInitialRequests: 3, // 入口文件的代码分割个数
automaticNameDelimiter: '~', // 组合文件连接的连接符
name: true, // 让cacheGroups里的名字有效
cacheGroups: { // 缓存组
vendors: { // 如果代码是node_modules里的则打包成vendors.js
test: /[\/]node_modules[\/]/,
priority: -10, // 优先级
fileName: 'vendors.js'
},
default: {
// minChunks: 2,
priority: -20,
reuseExistingChunk: true, // 如果一个模块被打包过直接复用
fileName: 'common.js'
}
}
}*/
},
performance: false // 不提示性能上的问题
}
module.exports = (env) => {
if (env && env.production) { // 线上环境
return merge(commonConfig, prodConfig)
} else { // 开发环境
return merge(commonConfig, devConfig)
}
}
webpack.dev.js
开发环境的配置
代码语言:javascript复制const path = require('path')
const webpack = require('webpack')
// function resolve(dir) {
// return path.join(__dirname, '../../../../', dir)
// }
const devConfig = { // 配置好后 npx webpack
mode: 'development',
// sourceMap 是一个映射关系,便于快捷定位文件错误位置
devtool: 'cheap-module-eval-source-map', // development 开发环境最优配置
devServer: { // 可以开启一个web服务器, 不生成dist目录,放到内存中
contentBase: './dist',
open: true, // 自动打开浏览器
port: 9999,
// historyApiFallback: false,
// hot: true,
// hotOnly: true, // 浏览器不刷新
proxy: { // 跨域代理
'/api': 'http://localhost:3030'
}
},
module: {
rules: [
{ // css-loader合并所有的css文件
test: /.css$/,
use: ['style-loader', 'css-loader', {
loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
options: {
config: {
path: path.resolve(__dirname, '../postcss.config.js'),
}
}
}]
},
{ // loader 执行的时候有先后顺序,由下到上,postcss-sass-css-style
test: /.scss$/,
use: [
'style-loader', // 用于挂载到html的head
{
loader: 'css-loader', // 用于把 css 文件合并成一个 css 文件
options: {
// 加上这个保证 index.scss里引入的scss也经过下面的loader处理
importLoaders: 2,
modules: false // css模块化
}
},
{
loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
options: {
config: {
path: path.resolve(__dirname, '../postcss.config.js'),
}
}
},
'sass-loader',
]
},
{ // 支持vue文件的处理
test: /.vue$/,
use: {
loader: 'vue-loader' // npm install vue-loader -D
}
},
]
},
plugins: [
new webpack.HotModuleReplacementPlugin() // 使用这个进行浏览器自动刷新和hot hotOnly有冲突
],
output: {
filename: '[name].js', // 打包文件的文件名
chunkFilename: '[name].js',
}
}
module.exports = devConfig
webpack.prod.js
生产环境的配置
代码语言:javascript复制const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 不支持热更新,在线上环境使用
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') // 压缩css生成的代码
const PurgecssPlugin = require('purgecss-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const prodConfig = { // 配置好后 npx webpack
mode: 'production', // development production
devtool: 'cheap-module-source-map', // production 生成环境
module: {
rules: [
{ // css-loader合并所有的css文件
test: /.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
options: {
config: {
path: path.resolve(__dirname, '../postcss.config.js'),
}
}
}
]
},
{
test: /.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
// 加上这个保证 index.scss里引入的scss也经过下面的loader处理
importLoaders: 2,
modules: false // css模块化
}
},
{
loader: 'postcss-loader', // css厂商前缀 npm i postcss-loader -D 配合 autoprefixer 插件
options: {
config: {
path: path.resolve(__dirname, '../postcss.config.js'),
}
}
},
'sass-loader'
]
},
{ // 支持vue文件的处理
test: /.vue$/,
use: {
loader: 'vue-loader' // npm install vue-loader -D
}
},
]
},
optimization: {
minimizer: [new OptimizeCssAssetsWebpackPlugin({ // 压缩css生成的代码
})]
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].chunk.css'
}),
// new PurgecssPlugin({ // 去除没用到的css
// paths: glob.sync(path.join(__dirname, '../src/index.html')) // src下所有的html
// }),
],
output: { // 为了防止浏览器缓存加入[contenthash],
// 代码改变[contenthash]才会改变,否则不会改变
filename: '[name].[contenthash].js', // 打包文件的文件名
chunkFilename: '[name].[contenthash].chunk.js',
}
}
module.exports = prodConfig