有些模块化的规范,比如commonJS等,浏览器是不支持的。那我们编写的代码想要部署使用,就要经过一系列解析变成浏览器可以识别的才可以。
webpack是一个模块打包器,主要目标是将javascript文件打包在一起,并在其中进行转换的工具。
1、出口入口
既然是打包工具,逻辑自然是"按照aa逻辑,将某些文件xx进行转换,然后输出为yy文件"。在这里,xx就是入口文件,yy就是出口文件,aa就是配置文件。
webpack的一般用法为webpack aaa.js /dust/bbb.js
这里,aaa.js即为入口,也就是要转换的文件(可以是多个),webpack会以这些文件为入口,将本文件及其依赖的文件进行处理。将bbb.js为出口,也就是转换后输出的结果文件。
如果每次都输入一堆命令,这太繁琐了,我们可以将相关内容都配置到一个文件中,这个文件就是webpack.config.js(当然,也是可以改的)。
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
}
注意,出口的path必须为绝对地址,如果直接写绝对地址,这太不灵活了,在不同机器或者一旦更换目录就无法运行。因此这里肯定是自动获取地址,这就依赖于node环境提供的path来完成,为了引入path,我们需要引入node。
引入node
npm init 初始化node环境,完成该步骤后会产生一个package.json,这里定了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本等)。
{
"name": "mywebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts":{
"test": "echo "this is test script",
"build": "webpack"
},
"author": "",
"devDependencies":{
//开发时依赖
},
"dependencies":{
//运行时依赖
}
}
scripts为我们自己定义的脚本,npm run xxx,这里的xxx便是我们scripts里边的key。
注意,如果如上配置,npm run build,实际会调用webpack命令进行打包。但这里跟直接在命令行运行webpack不同的是npm run所运行的webpack会优先使用webpack的本地版本,而命令行的webpack命令,如果没指定,则默认使用全局webpack版本。如果本项目来自互联网,则很可能导致因为项目默认的webpack版本跟我们全局安装的webpack版本不一致而打包失败!!
2、loader
loader是webpack非常核心的概念。
webpack用来做什么呢
1.处理js代码,并自动处理js之间相关的依赖;
2.将ES6代码转为ES5,将TypeScript转为ES5,将scss、less转为css,将.jsx、.vue转为js文件等;
但实际上webpack本身并不支持以上功能,这些功能都是对应的loader完成的。loader的使用过程:
1.通过npm安装需要用到的loader;
2.在webpack.config.js中的modules关键字下进行配置;
比如,我们要把一个css文件也要加入打包,则需要一个css-loader:
const path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules:[
{ test: /.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
这里要注意的是css-loader只负责css文件加载,style-loader负责将样式添加到DOM中,故而要将css打包并应用生效至少需要2个loader。webpack的特殊之处还在于:当使用多个loader时,使用顺序为从右往左依次调用,故而css-loader要放在style-loader的右边(也就是后边)。
两者都是编译时使用,故而安装选择--save-dev就可以了。
注意rules为数组,如果需要对多种文件类型进行处理,对每个类型进行单独配置一个对象即可。(比如.css,.less, .scss等)。
对于图片的处理,请参照官网,使用文件处理的url-loader,图片加载还可以配置大小限制。过大的图片会使用file-loader,但页面引用路径不对(没引用dist中的),处理不爱就发是module.exports中添加publicPath:"dist/",这样一来,页面引用的图片地址便都是正确的了。
{
test: /.(png|jpg|gif|jpeg)$/,
use [
{
loader: 'url-loader',
options: {limit: 13000},
name: 'img/[name].[hash:8].[ext]'
}
]
}
注意,以上配置中,limit为图片大小限制,name为生成的图片命名规则:文件要打包的文件夹/图片原名称.为防止重名而生成的8位哈希值.图片原来的扩展名
3、vue配置
我们先来配置普通的vue(没有用loader解析.vue文件)。操作步骤如下:
- npm install vue --save
全局安装vue,因为编译跟运行都需要; - 配置vue
module.exports = {
//其它配置
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
}
- 在需要的地方引入vue
import Vue from 'vue'
之所以在2需要配置alias,是因为npm install 之后的vue有2个版本:
runtime-only --> 代码中不可以有任何template。根vue的app也被视为template
runtime-compiler --> 代码中,可以有template,因为有compiler可以用于编译template
默认使用的runtime-only,需要手动指定为后者。也就是关于别名vue$的配置部分。
vue-loader
vue-loader的配置思路跟普通文件解析并没有什么区别,单独来说,只是因为当前我们关注点在vue而已。步骤如下:
- npm install vue-loader vue-template-compiler --save-dev
加载两个loader:分别用于加载.vue文件跟进行编译解析; - 配置loader
{
test: /.vue$/,
use: ['vue-loader']
}
注意vue-loader使用13.xx版本。在14版本及以后,需要额外单独配置插件;
3.npm run build编译后使用
4、plugin插件
plugin跟loader有啥区别?
loader主要用于转换某些类型的模块,是个转换器。
plugin是插件,是对webpack本身的扩展,是扩展器。
插件的使用步骤跟loader一样,先npm install,再配置,然后就可以使用了。
比如,打包html的插件html-webpack-plugin:
- npm install html-webpack-plugin --save-dev 引入插件
- 配置插件:
const HtmlWebpackPlugin = require('html-webpack-plugin')
//其它代码
plugins: [
new HtmlWebpackPlugin({
template: 'index.html'
})
]
5、本地服务器
- 安装服务器,npm install webpack-dev-server;
- 配置脚本:
//package.json
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --open"
},
//webpack.config.js
devServer: {
contentBase: './dist', //响应目录
inline: true, //实时跟新
}
- 启动,npm run dev
启动后可以自动打开浏览器,且本地代码进行修改后会实时在页面展现。
注意,webpack,webpack-cli,webpack-dev-server有版本要求,如果不匹配会报错。本地使用的为webpack4.41.0, webpack-cli3.3.0, webpack-dev-server3.11.0
6、配置分离
需要插件webpack-merge
webpack-merge将base.config.js跟dev.config.js合并
//dev.config.js
const webpackMerge = require('webpack-merge')
module.exports = webpackMerge.merge(baseConfig, {
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
minify: {
removeComments: false,
removeAttributeQuotes: false
}
}),
],
});
//package.json
"scripts": {
"build": "webpack --mode development --config ./build/dev.config.js",
"dev": "webpack-dev-server --mode development --config ./build/dev.config.js"
}
注意相对路径都是相对于package.json的
另:npm 清理缓存 npm cache clear --force