webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
安装
webpack 最新版本 v4.26.0
github star:45.292k
需要同时安装 webpack
、webpack-cli
、webpack-dev-server
,建议安装在每个独立项目而不是全局,这样方便单独使用 webpack3 或者 webpack4
yarn add webpack webpack-cli webpack-dev-server -D
或者:
cnpm install webpack webpack-cli webpack-dev-server -D
2018年8月25号webpack4正式发布。再次之后只要使用npm install webpack命令,默认安装的就是版本4
基础版
webpack4 会根据环境自动设置一些默认配置,下面是一个最基础的配置:
package.json
// --config webpack.config.js 配置文件的路径
// --mode=production 用到的模式
// --progress 打印出编译进度的百分比值
"scripts": {
"dev": "webpack-dev-server --progress --mode=development --config webpack.config.js",
"build": "webpack --progress --mode=production --config webpack.config.js",
},
webpack.config.js
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/', // 资源引用路径前后都有斜杠
filename: '[name].js'
},
devServer: {
open: true, // 自动打开浏览器
host: '0.0.0.0',
port: 3003,
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, 'template.html'),
}),
new webpack.HotModuleReplacementPlugin(), // 开启webpack热更新功能
new webpack.NoEmitOnErrorsPlugin(), // webpack编译出错跳过报错阶段,在编译结束后报错
],
}
浏览器输入 http://0.0.0.0:3003/webpack-dev-server
可以查看开发环境文件结构
实用版
package.json
在实际使用中建议分开配置,生产环境和开发环境分别对应一个配置文件
// --config config/webpack.dev.js 配置文件的路径
// --progress 打印出编译进度的百分比值
"scripts": {
"start": "webpack --progress --config config/webpack.dll.js",
"dev": "webpack-dev-server --progress --config config/webpack.dev.js",
"build": "webpack --progress --config config/webpack.prod.js"
},
base.conf.js
把公共配置提取到一个公用文件 base.conf.js 中,后期所有修改都在这个文件,其他配置文件不动,减小人为错误
const os = require('os')
const getIp = () => { // 获取本地ip
var interfaces = os.networkInterfaces();
for (var devName in interfaces) {
var iface = interfaces[devName];
for (var i = 0; i < iface.length; i++) {
var alias = iface[i];
if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
return alias.address;
}
}
}
}
module.exports = {
base: {
rootPath: '/',
fileName: 'dist',
filePath: 'dist/static',
},
dev: {
useEslint: true,
host: getIp(),
port: 3001,
proxy: [
{
context: ['/v2', '/xw', '/wap', '/information'],
target: 'https://xwm.jindanlicai.com/',
changeOrigin: true,
cookieDomainRewrite:{
"*":getIp()
}
},
]
}
}
webpack.base.js
提取开发环境和取生产环境的相同部分到基础配置文件 webpack.base.js 中
const config = require('./base.conf.js') // 配置文件
const path = require('path')
const webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HappyPack = require('happypack') // 多进程 默认三个
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })
// 处理路径
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
// eslint检测
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
exclude: /node_modules/,
include: [resolve('src')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: true
}
})
// 获取当前环境
const prod = process.env.NODE_ENV === 'production'
module.exports = {
context: path.resolve(__dirname, '../'), // 作用于entry 和 loader
entry: {
index: './src/main.js',
},
output: {
path: resolve(`${config.base.filePath}`), // 输出到static这个地址 只能是绝对路径
filename: 'js/[name].js',
chunkFilename: 'js/[name]_[chunkhash:6].js'
},
resolve: {
extensions: ['.css', '.less', '.js', '.vue', '.json'], // 使用的扩展名
alias: {
// 'vue$': 'vue/dist/vue.esm.js', // 模块别名列表
'@': resolve('src'),
}
},
module: {
// 忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制,忽略部分插件可以提高构建性能
noParse: /^(vue|vue-router|vuex|vuex-router-sync|axios)$/,
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
include: resolve('src')
},
{
test: /\.pug$/,
loader: 'pug-plain-loader',
include: resolve('src')
},
{
test: /\.css$/,
oneOf: [
// 这里匹配 `