在1中对webpack有了初步的认识,了解了webpack到底是什么,模块是什么,为什么要有配置文件,接下来继续思考,之前我们打包的都是一个js文件,那如果是一张图片呢,一个css文件呢,一个vue文件呢,webpack也能直接识别么,当然不能,webpack根本不认识他们,这就有了loader,在配置文件中配置如果他是什么文件就用什么loader去解析他,如果有没有识别出来的类型,webpack当然就无法打包了。
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'dist')
},
module: {
rules: [{
test: /\.(jpg|png|gif)$/,//如果是jpg文件
use: {
loader: 'file-loader'//就用file-loader去解析
}
},{
test: /\.vue$/,//如果是vue文件
use: {
loader: 'vue-loader'//vue-loader去解析
}
},{
test: /\.css$/,
use: ['style-loader','css-loader']//多个loader可以用数组,loader的执行顺序是从下到上,从右到左
}]
}
}
loader是有执行顺序的,执行顺序是从下到上,从右到左
这些loader底层会把这些webpack不能识别的文件转换成可以识别的样子,这些loader还会提供许多的配置参数以满足各种各样得需求,可以把这些需求写到options来配置它,我们举个简单的例子
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'dist')
},
module: {
rules: [{
test: /\.(jpg|png|gif)$/,//如果是jpg文件
use: {
loader: 'file-loader'//就用file-loader去解析,
options: {
name: '[path][name].[ext]'//指定打包的名称和原图片名称一致,不写这个打包出来的图片名称实际是图片的地址
}
}
},{
test: /\.vue$/,//如果是vue文件
use: {
loader: 'vue-loader'//vue-loader去解析
}
}]
}
}
还支持不同种的写法,上下这两种意思差不多
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'dist')
},
module: {
rules: [{
test: /\.(jpg|png|gif)$/,//如果是jpg文件
use: {
loader: 'file-loader'//就用file-loader去解析,
options: {
name (file) {
if (env === 'development') {
return '[path][name].[ext]'
}
return '[hash].[ext]'
}
}
}
},{
test: /\.vue$/,//如果是vue文件
use: {
loader: 'vue-loader'//vue-loader去解析
}
}]
}
}
这些loader支持哪些方法大可不必都背下来,只需要记住一些常用的即可,忘记了也可以在相关文档中找的到文档,提示报错记得查看有没有安装相应loader
对于样式的打包还有一个疑问,对于某些css3样式的兼容,一些厂商前缀是如何自动添加的呢,没想到吧,有了webpack不用再一个一个的补全厂商前缀了!
其实是用的就是postcss-loader,我们来看官方文档里是如何使用的,首先添加一个postcss-loader,然后创建一个postcss.config.js文件,实际就是postcss-loader中的autoprefixer插件帮我们自动添加的厂商前缀
const path = require('path')
module.exports = {
mode: 'development',
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'dist')
},
module: {
rules: [{
test: /\.(jpg|png|gif)$/,//如果是jpg文件
use: {
loader: 'file-loader'//就用file-loader去解析
}
},{
test: /\.vue$/,//如果是vue文件
use: {
loader: 'vue-loader'//vue-loader去解析
}
},{
test: /\.css$/,
use: ['style-loader','css-loader','postcss-loader']//多个loader可以用数组,loader的执行顺序是从下到上,从右到左
}]
}
}
postcss.config.js
module.export = {
plugins: [
require('autoprefixer')
]
}
接下来我们学习一下loader设置一些参数,还以css或scss文件举例,抽出关键代码来看
{
test: /\.scss$/,
use: ['style-loader',
'css-loader',
'scss-loader'
'postcss-loader'
]//多个loader可以用数组,loader的执行顺序是从下到上,从右到左
}
思考一个问题,我们说从js引入一个scss文件时,会从loader中从下到上从右到左依次使用loader,但是,当该样式文件内部又@import引入一个样式文件时,就可能不会从下到上从右到左来使用loader了,只会使用css-loader,显而易见这不是我们想要的结果,所以loader也可以来设置参数解决问题
{
test: /\.scss$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
importLoaders:2,
modules:true//开启样式模块化,在js中可以限制样式作用范围
}
},
'scss-loader'
'postcss-loader'
]//多个loader可以用数组,loader的执行顺序是从下到上,从右到左
}
importLoaders:2的含义我们可以理解为,当使用css-loader之前也要使用【下面】两种loader,也就是要使用’scss-loader’和’postcss-loader’,importLoaders默认值为0;
如何使用webpack打包字体文件
plugin
再来举个简单的例子来理解plugin,打包生成的dist目录下的index.html文件,如果我们想在这个文件下生成一个根div该怎么办呢,不能每次都手动写一下,如果我们改了入口文件的名字呢,我们想让他先删除dist目录再重新安装,可以使用plugin
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
//...
plugins:[
new HtmlWebpackPlugin({
template:'index.html'
}),new CleanWebpackPlugin(['dist'])
]
entry和output
entry: './index.js',
当入口不设置的时候,默认为main.js,实际上是
entry: {
main:'./index.js',
}
当你想打包两份的时候,可以这样写:
entry: {
main:'./index.js',
sub:'./index.js',
}
这样就会生成两个js文件,名称分别为main.js和sub.js,但是真的是我们想象中的这样么,实际上当你打包后会报错:打包多个文件生成了相同的名字,原因是output名称设置有问题
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'dist')
},
这是我们的设置的output,可以看到输出的都是’bundle.js,但是我们打包的是两个文件,所以我们可以改下,这样就没问题了
output: {
filename: '[name].js',
path: path.resolve(__dirname,'dist')
},
除此之外还有很多的设置,例如在index.html中引入打包后的js都是相对路径,例如src="./main.js",如果我们想加上我们自己的域名,也可以在output中配置
output: {
publicPath:'http://cdn.com.cn',
filename: '[name].js',
path: path.resolve(__dirname,'dist')
},
我们可以在官方文档中查到更多的配置
本章结束
本章结束时,建议把官方文档中的讲解看一遍,相信会加深你的理解。