Description
本文只讨论webpack做为打包工具,生成生产环境所必须的js、css的基本配置
具体实现如下几项:
- 静态处理: 包括css和js 压缩打包,以及css的抽取,es6语法支持
- 图片处理:小图改为data uri
- 静态文件注入html
目录结构如下:
首先是 webpack基本配置(entry & output)
const path = require('path');
var assetsPath = function (_path) {
var assetsSubDirectory = 'static'
return path.posix.join(assetsSubDirectory, _path)
}
module.exports = {
entry: './SRC/main.js', //指定入口文件
output: {
filename: assetsPath('src/main.[hash:7].js'), // 生成文件名
path: path.resolve(__dirname, 'dist') // 生成文件根目录
}
}
静态文件处理:
- 处理css:
-
基础:
一般来说需要css-loader 和 style-loader。由于webpack的入口文件必须是js,我们一般需要在js中通
过import 引入css源文件,css-loader用于解析css文件,style-loader用于将解析后的css代码嵌入到js
中。
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
-
将css抽取为独立文件
经过css-loader和style-loader的处理之后,css文件被成功插入到js中。这种做法存在的问题是,如果css过大,会导致js单文件过大,因此我们需要将css文件单独抽取出来生成独立文件。
我们采用extract-text-webpack-plugin 插件。它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载来实现css文件的抽取。
下图是官方提供优缺点对比
使用该插件,我们需要在已有的loader,创建一个提取loader
处理css的rules变更为:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin ({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
}
之后在plugin中指定抽取文件的生成目录和文件名了:
plugins: {
new ExtractTextPlugin({
filename: assetsPath('css/[name].[contenthash].css')
})
}
至此我们完成了css静态文件的打包和抽取。
处理js:
- 解析js
:支持es6语法,引入了babel-loader
module:{
rules:[
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
}
}
}
- 压缩js :
webpack 自带uglifyjs插件:
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: { //压缩
warnings: false
},
sourceMap: true //生成sourceMap
})
]
处理图片
原则上使用url-loader和file-loader都可以。url-loader可以将低于limit的图片编译为data uri插入css,但url-loader是基于file-loader的,所以我们把两者结合起来一起使用。
module:{
rules:[
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000, //低于10000的图片编译为data uri
name: assetsPath('img/[name].[hash:7].[ext]')
}
}
]
}
html处理
html-webpack-plugin插件根据模板生成编译后的html文件,并将编译后的静态资源注入html
plugins:[
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'SRC/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
}
})
]
总结
package.json
"scripts": {
"build": "webpack"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"css-loader": "^0.28.9",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^1.1.6",
"html-webpack-plugin": "^2.30.1",
"style-loader": "^0.20.1",
"url-loader": "^0.6.2",
"webpack": "^3.10.0"
}
webpack.config.js
const path = require('path');
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
assetsPath = function (_path) {
var assetsSubDirectory = 'static'
return path.posix.join(assetsSubDirectory, _path)
}
module.exports = {
entry: './SRC/main.js',
output: {
filename: assetsPath('src/main.[hash:7].js'),
path: path.resolve(__dirname, 'dist')
},
module:{
rules:[
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: assetsPath('img/[name].[hash:7].[ext]')
}
},
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'SRC/index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
}
}),
new ExtractTextPlugin({
filename: assetsPath('css/[name].[contenthash].css')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
]
};