webpack 核心概念:
webpack流程:
webpack启动后会从 Entry 里配置的 Module 开始递归解析 Entry 依赖的全部Module.每找到一个Module,就会根据配置的Loader去找出对应的转换规则,对Module进行转换后,再解析出当前的Module依赖的Module.这些模块会以Entry为单位进行分组,一个Entry和其全部依赖的Module被分到一个组也就是一个Chunk。最好Webpack会把全部Chunk转换成文件输出。在整个流程中Webpack会在恰当的时机执行Plugin里定义的逻辑。javascript
下面咱们开始从零开始配置一个支持打包图片,CSS,LESS,SASS,支持ES6/ES7和JSX语法,并对代码进行压缩的webpack配置.css
更多文章可戳: github.com/YvetteLau/B…html
1. 最简webpack配置
首先初始化npm和安装webpack的依赖:前端
npm init -y
npm install --save-dev webpack webpack-cli
复制代码
配置 webpack.config.js 文件以下:java
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/'
}
}
复制代码
说明: publicPath 上线时配置的是cdn的地址。node
使用命令进行打包:react
webpack --mode production
复制代码
也能够将其配置到 package.json 中的 scripts 字段.webpack
入口文件为 src/index.js, 打包输出到 dist/bundle.js.git
2. 使用模板 html
html-webpack-plugin 能够指定template模板文件,将会在output目录下,生成html文件,并引入打包后的js.github
安装依赖:
npm install --save-dev html-webpack-plugin
复制代码
在 webpack.config.js 增长 plugins 配置:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//...other code
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html')
})
]
}
复制代码
HtmlWebpackPlugin 还有一些其它的参数,如title(html的title),minify(是否要压缩),filename(dist中生成的html的文件名)等
3. 配置 webpack-dev-server
webpack-dev-server提供了一个简单的Web服务器和实时热更新的能力
安装依赖:
npm install --save-dev webpack-dev-server
复制代码
在 webpack.config.js 增长 devServer 配置:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
//...other code
devServer: {
contentBase: './dist',
port: '8080',
host: 'localhost'
}
}
复制代码
在 package.json 的 scripts 字段中增长:
webpack-dev-server --mode development
复制代码
以后,咱们就能够经过 npm run dev , 来启动服务。
更多 webpack-dev-server 的知识,请访问: webpack.js.org/configurati…
4. 支持加载css文件
经过使用不一样的 style-loader 和 css-loader, 能够将 css 文件转换成JS文件类型。
安装依赖:
npm install --save-dev style-loader css-loader
复制代码
在 webpack.config.js 中增长 loader 的配置。
module.exports = {
//other code
module: {
rules: [
{
test: /\.css/,
use: ['style-loader', 'css-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
}
]
}
}
复制代码
loader 能够配置如下参数:
若是须要给loader传参,那么可使用use+loader的方式,如:
module.exports = {
//other code
module: {
rules: [
{
use: [{
loader: 'style-loader',
options: {
insertAt: 'top'
}
},
'css-loader'
],
//....
}
]
}
}
复制代码
5. 支持加载图片
若是但愿图片存放在单独的目录下,那么须要指定outputPath
安装依赖:
npm install --save-dev url-loader file-loader
复制代码
在 webpack.config.js 中增长 loader 的配置(增长在 module.rules 的数组中)。
module.exports = {
//other code
module: {
rules: [
{
test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
outputPath: 'images'
}
}
]
}
]
}
}
复制代码
6.支持编译less和sass
有些前端同事可能习惯于使用less或者是sass编写css,那么也须要在 webpack 中进行配置。
安装对应的依赖:
npm install --save-dev less less-loader
npm install --save-dev node-sass sass-loader
复制代码
在 webpack.config.js 中增长 loader 的配置(module.rules 数组中)。
module.exports = {
//other code
module: {
rules: [
{
test: /\.less/,
use: ['style-loader', 'css-loader', 'less-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.scss/,
use: ['style-loader', 'css-loader', 'sass-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
}
]
}
}
复制代码
7.支持转义 ES6/ES7/JSX
ES6/ES7/JSX 转义须要 Babel 的依赖,支持装饰器。
npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread
复制代码
在 webpack.config.js 中增长 loader 的配置(module.rules 数组中)。
module.exports = {
//other code
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/react'],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
}
],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
},
]
}
}
复制代码
8.压缩JS文件
安装依赖:
npm install --save-dev uglifyjs-webpack-plugin
复制代码
在 webpack.config.js 中增长 optimization 的配置
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
//other code
optimization: {
minimizer: [
new UglifyWebpackPlugin({
parallel: 4
})
]
}
}
复制代码
9.分离CSS(若是CSS文件较大的话)
由于CSS的下载和JS能够并行,当一个HTML文件很大的时候,能够把CSS单独提取出来加载
npm install --save-dev mini-css-extract-plugin
复制代码
在 webpack.config.js 中增长 plugins 的配置,而且将 'style-loader' 修改成 { loader: MiniCssExtractPlugin.loader}。
CSS打包在单独目录,那么配置filename。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
//other code
module: {
rules: [
{
test: /\.css/,
use: [{ loader: MiniCssExtractPlugin.loader}, 'css-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.less/,
use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.scss/,
use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
]
}
复制代码
10.压缩CSS文件
安装依赖:
npm install --save-dev optimize-css-assets-webpack-plugin
复制代码
在 webpack.config.js 中的 optimization 中增长配置
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
//other code
optimization: {
minimizer: [
new OptimizeCssAssetsWebpackPlugin()
]
}
}
复制代码
11.打包前先清空输出目录
npm install --save-dev clean-webpack-plugin
复制代码
在 webpack.config.js 中增长 plugins 的配置
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
//other code
plugins: [
new CleanWebpackPlugin()
]
}
复制代码
至此,webpack配置已经基本能知足需求。
完整webpack.config.js和package.json文件
webpack.config.js文件:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/'
},
devServer: {
contentBase: './dist',
port: '8080',
host: 'localhost'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/react'],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
}
],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
},
{
test: /\.css/,
use: [{ loader: MiniCssExtractPlugin.loader}, 'css-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.less/,
use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.scss/,
use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'sass-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
},
{
test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
outputPath: 'images'
}
}
]
}
]
},
optimization: {
minimizer: [
new UglifyWebpackPlugin({
parallel: 4
}),
new OptimizeCssAssetsWebpackPlugin()
]
},
plugins: [
new htmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'),
}),
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
new CleanWebpackPlugin()
]
}
复制代码
package.json文件:
{
"name": "webpk",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"dev": "webpack-dev-server --mode development"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/plugin-proposal-decorators": "^7.4.0",
"@babel/plugin-proposal-object-rest-spread": "^7.4.0",
"@babel/preset-env": "^7.4.1",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5",
"clean-webpack-plugin": "^2.0.1",
"css-loader": "^2.1.1",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.1.2",
"url-loader": "^1.1.2",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"
},
"dependencies": {
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-redux": "^6.0.1",
"redux": "^4.0.1"
}
}
复制代码
更多loader和plugin的参数能够参考: www.webpackjs.com/loaders/ www.webpackjs.com/plugins/
若是你有其它的webpack配置需求,欢迎留言~
谢谢您花费宝贵的时间阅读本文,若是本文给了您一点帮助或者是启发,那么不要吝啬你的赞和Star哈,您的确定是我前进的最大动力。github.com/YvetteLau/B…