1 基本概念
入口(entry)
入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
。
加载程序loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
插件(plugins)
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
2 配置结构
// webpack.config.js
module.exports = {
entry: '', // 入口配置
output: {}, // 输出配置
module: {}, // 放置loader加载器,webpack本身只能打包commonjs规范的js文件,用于处理其他文件或语法
plugins: [], // 插件,扩展功能
// 以下内容进阶篇再涉及
resolve: {}, // 为引入的模块起别名
devServer: {} // webpack-dev-server
};
3 基本功能
3.1输入/输出配置
entry
传入数组相当于将数组内所有文件都打包到bundle.js中。
outpu指定输出文件名,输出的路径
const path = require('path');
module.exports = {
entry: ['./src/index.js', './src/index2.js'], // 入口文件
output: {
filename: 'bundle.js', // 打包输出文件名
path: path.join(__dirname, './dist') // 打包输出路径(必须绝对路径,否则报错)
}
};
3.2 清空某目录或子目录及文件
npm install -D clean-webpack-plugin
// webpack.config.js
const CleanWebpackPlugin = require('clean-webpack-plugin');
const cdnDir = path.resolve(__dirname, '../../../', 'imgcache.gtimg.cn/vip/')
module.exports = {
...
plugins: [
new CleanWebpackPlugin(['dist']), // 清空项目根目录下dist
]
};
3.3 html自动构建
npm install html-webpack-plugin -D
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
filename: path.join(__dirname, 'entry.html'),
// 生成的html(绝对路径:可用于生成到根目录)
filename: 'html/entry.html',
// 生成的html文件名(相对路径:将生成到output.path指定的dist目录下)
template: './src/index.html' // 以哪个文件作为模板,不指定的话用默认的空模板
})
]
};
3.4 CSS处理——内联
npm install -D css-loader # 负责处理其中的@import和url()
npm install -D style-loader # 负责内联
npm install -D less less-loader # less编译,处理less文件
module配置
// index.js
import './style/index.css';
import './style/test.less';
// webpack.config.js
module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
// 从右到左,loader安装后无需引入可直接使用
use: ['style-loader', 'css-loader']
},
{
test: /\.less$/,
use: [
{loader: 'style-loader'},
{loader: 'css-loader'},
{loader: 'less-loader'}
]
}
]
}
};
3.5 CSS处理——合并抽离
npm install -D extract-text-webpack-plugin@next
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// 实例化1:用于CSS
const extractCSS = new ExtractTextPlugin({
disable: process.env.NODE_ENV == 'development' ? true : false, // 开发环境下直接内联,不抽离
filename: 'style/extractFromCss.css', // 单个entry时,可写死
filename: 'style/[name].css', // 多entry时
});
// 实例化2:用于LESS
const extractLESS = new ExtractTextPlugin({省略...});
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: extractCSS.extract({
fallback: 'style-loader',
use: 'css-loader'
})
},
{
test: /\.less$/,
use: extractLESS.extract({
fallback: 'style-loader',
use: ['css-loader', 'less-loader']
})
}
]
},
plugins: [extractCSS, extractLESS]
};
3.6 图片(字体/svg)处理
npm install -D url-loader file-loader
3.7 ES6转义
npm install -D babel-core babel-loader babel-preset-env babel-preset-stage-0
/ webpack.config.js
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/, // npm包不做处理
include: /src/, // 只处理src里面的
use: {
loader: 'babel-loader',
options: {
presets: ['env', 'stage-0'] // 【重要】顺序右到左,先处理高级或特殊语法
}
}
}
]
}
3.8 webpack-dev-server
npm install -D webpack-dev-server
webpack-dev-server是一个小型的Node.js Express
服务器,它使用webpack-dev-middleware
来服务于webpack的包
contentBase
用于告诉服务器文件的根目录。这主要用来需要引用静态文件的时候。
host
设置服务器的主机号,默认是localhost,但是可以自己进行设置,如:
host: "0.0.0.0"
port
设置端口号,如下面的7000
devServer: {
port:7000
}
hot 和 inline
自动刷新和模块热替换机制
注意,如果你的项目中使用了热模块替换机制,HotModuleReplacementPlugin插件会自动添加到项目中,而不需要再在配置文件中做添加。
webpack-dev-server有两种模式可以实现自动刷新和模块热替换机制
1. Iframe mode(默认,无需配置)
页面被嵌入在一个iframe里面,并且在模块变化的时候重载页面
2.inline mode(需配置)添加到bundle.js中
当刷新页面的时候,一个小型的客户端被添加到webpack.config.js的入口文件中
proxy
重定向是解决跨域的好办法,当后端的接口拥有独立的API,而前端想在同一个domain下访问接口的时候,可以通过设置proxy实现。
如果后端接口地址是192.168.10.10:1000,你可以这样设置:
proxy: {
"/api": "http://192.168.10.10:1000"
}
publicPath
用于设置编译后文件的路径,假设服务器的运行地址是 http://localhost:8080,输出文件名设置为bundle.js,那么默认情况下publicPath是”/”。
4 开发/生产环境
开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。
npm install --save-dev webpack-merge
project
webpack-demo
|- package.json
|- webpack.common.js
|- webpack.dev.js
|- webpack.prod.js
|- /dist
|- /node_modules
webpack.common.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js'
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Production'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
plugins: [
...
]
});
webpack.prod.js
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
plugins: [
...
]
});
4.1 NPM Scripts
现在,我们把 scripts
重新指向到新配置。我们将 npm start
定义为开发环境脚本,并在其中使用 webpack-dev-server
,将 npm run build
定义为生产环境脚本:
package.json
{
"name": "development",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^0.1.17",
"css-loader": "^0.28.4",
"csv-loader": "^2.1.1",
"express": "^4.15.3",
"file-loader": "^0.11.2",
"html-webpack-plugin": "^2.29.0",
"style-loader": "^0.18.2",
"webpack": "^3.0.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0",
"xml-loader": "^1.2.1"
}
}