Webpack
一、什么是Webpack
一款JavaScript应用的静态模块打包工具。
二、Webpack安装
安装webpack首先需要安装Node.js,Webpack依赖Node环境,Node.js自带npm工具(node packages manager)(包管理工具)。
查看自己的Node版本:
> node -v
全局安装webpack(此处指定版本号):
> npm install webpack@3.6.0 -g
注意:在此处进行全局安装后,后面还会进行局部安装。
为什么全局安装后,还需要进行局部安装呢?
一个项目往往依赖特定的webpack版本,全局的版本可能和这个项目的webpack版本不一致,导致打包出现问题。所以通常一个项目,都有自己的局部的webpack。
在终端直接执行webpack命令,使用的全局安装的webpack;
当在package.json中定义了包含了webpack命令的scripts时,使用的是局部webpack。
三、webpack的基本使用
> webpack ./src/main.js ./dist/bundle.js
把./src/main.js文件(只需处理入口文件,webpack会处理模块依赖关系)打包至./dist/bundle.js文件。
index.html文件中只需引用./dist/bundle.js文件。
webpack.config.js配置和package.json配置
如果项目中依赖node中的包 ,需要先进行npm初始化:> npm init
,创建package.json文件,该文件描述项目的一些信息。
安装局部webpack:> npm install webpack@3.6.0 --save-dev
(–save-dev 安装开发时依赖)
webpack.config.js文件:
// webpack.config.js与index.html同级
// 导入path包
const path = require('path')
module.expotrs = {
// 指定webpack打包入口文件
entry: './src/main.js',
// 指定webpack打包出口文件
output: {
// path需要使用绝对路径
// 使用path.resolve()函数对路径进行拼接
// __dirname是一个表示当前文件所在目录的绝对路径的全局变量
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
}
}
package.json文件:
// package.json与index.html同级
{
"name": "meetwebpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
// 在package.json的scripts中定义自己的执行脚本,
// 在终端执行npm run xxx时(如npm run test)会执行它冒号后的内容
// package.json中的script脚本在执行时,会按照一定的顺序寻找命令对应的位置,
// 首先,会寻找本地的node_modules/bin路径中对应的命令
// 如果没有找到,会去全局的环境变量中寻找
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"author": "",
"license": "ISC",
"devDependencies": {
// 开发时依赖
// npm安装包时自动添加
"webpack": "^3.6.0"
},
"dependencies": {
// 运行时依赖
// npm安装包时自动添加
}
}
此时在命令行执行nom run duild
即可按照要求打包
四、loader
在上面的代码中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间的相关的依赖。但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css/图片,也包括一些高级的将ES6 转为ES5代码,将TypeScript转为ES5代码,将scss/less转为css,将.jsx、.vue文件转为js文件等等。
对于webpack本身的能力来说,对于这些转化是不支持的。
此时需要给webpack扩展对应的loader。
loader使用过程
loader中文文档:https://www.webpackjs.com/loaders,根据自己的需求选择对应的loader。
步骤一:通过npm安装需要使用的loader
步骤二:在webpack.config.js中的modules关键字下进行配置
(在官方文档中有对应教程)
例1:webpack中使用css文件的配置
在main.js文件中添加依赖:
require('./css/normal.css')
安装css-loader:
> npm install --save-dev css-loader
安装style-loader:
> npm install style-loader --save-dev
css-loader只负责将css文件进行加载,style-loader负责将样式添加到dom中。
配置webpack.config.js文件:
...
module.exports = {
...
module:{
rules:[
{
// 正则表达式 匹配所有的css文件
test:/\.css$/,
// 使用多个loader时,是从后向前使用
use:['style-loader','css-loader']
}
]
}
}
例2:webpack中使用less文件的配置
在main.js文件中添加依赖:
require('./css/special.less')
安装less-loader:
> npm install --save-dev less-loader less
less-loader只负责将less文件进行加载,less包用于解析less文件。
配置webpack.config.js文件:
...
module.exports = {
...
module:{
rules:[
...,
{
test: /\.less$/,
// 对象格式方便添加更多配置
use: [{
loader: "style-loader"
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}]
}
]
}
}
例3:webpack中图片文件处理的配置
在css文件中使用图片:
body {
background: url("../img/test.jpg");
}
安装url-loader:
> npm install --save-dev url-loader
配置webpack.config.js文件:
需要设置limit大小,当加载的图片小于limit时,url-loader会将图片编译成base64字符串形式;
当加载的图片大于limit时,需要使用file-loader模块加载。
...
module.exports = {
...
module:{
rules:[
...,
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
// 当加载的图片小于limit时,url-loader会将图片编译成base64字符串形式
// 当加载的图片大于limit时,需要使用file-loader模块加载
limit: 13000
}
}]
}
}
}
使用file-loader:
安装file-loader:安装完后不用配置就可以使用
> npm install --save-dev file-loader
当使用file-loader之后,会在dist文件夹中生成32位哈希值名字的图片
配置webpack.config.js文件:
...
module.exports = {
...,
output: {
...,
// 配置打包后的文件路径名避免引用图片时出现路径错误
// 此时,index.html文件存放在项目的根目录下
publicPath: 'dist/'
},
module:{
rules:[
...,
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
...,
// 配置打包后的图片的名字
// img: 文件要打包到的文件夹名
// [name]: 获取图片原来的名字,放在该位置
// [hash8]: 为了防止图片命名冲突,依然使用hash,但是我们只保留8位
// [ext]: 使用图片原来的扩展名
name: 'img/[name].[hash:8].[ext]'
}
}]
}
}
例4:webpack中ES6语法的处理
需要使用babel将ES6的语法转成ES5。
安装babel对应的loader:
> npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
配置webpack.config.js文件:
...
module.exports = {
...
module:{
rules:[
...,
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [{
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}]
}
}
}
五、Plugin
webpack中的插件,就是对webpack的现有功能进行扩充,比如打包优化、文件压缩等。
例1:添加版权信息的Plugin(BannerPlugin)
配置webpack.config.js文件:
...
const webpack = require('webpack')
module.exports = {
...
plugins: [
new webpack.BannerPlugin('最终版权归xxx所有')
]
}
例2:HtmlWebpackPlugin的使用
目前index.html文件存放在项目的根目录下,而在发布项目时,发布的是dist文件夹中的内容,此时,需要将index.html文化部打包到dist文件夹中。
HtmlWebpackPlugin插件可以帮我们自动生成一个index.html文件(可以指定模板),并将打包的js文件自动通过script标签插入到body中。
安装HtmlWebpackPlugin:
> npm install html-webpack-plugin --save-dev
配置webpack.config.js文件:
...
module.exports = {
... // 删除之前在output中添加的publicPath属性,否则插入的script标签中的src可能会有问题
plugins: [
...,
new htmlWebpackPlugin({
// template指定根据什么模板来生成index.html
template: 'index.html'
})
]
}
例3:js文件压缩的Plugin(UglifyWebpackPlugin)
在项目发布之前,必须对js等文件进行压缩处理。
安装UglifyWebpackPlugin:
(指定版本号1.1.1是为了和vue-cli2保持一致,此处可根据自己的情况修改)
> npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
配置webpack.config.js文件:
...
const uglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
...,
plugins: [
...,
new uglifyJsPlugin()
]
}
六、webpack-dev-server搭建本地服务器
webpack提供了一个可选的本地开发服务器,这个本地服务器基于Node.js搭建,内部使用express框架,可以实现让浏览器自动刷新显示修改后的结果。
安装:
> npm install --save-dev webpack-dev-server@2.9.3
配置webpack.config.js文件:
...
const uglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
...,
devServer: {
// contentBase:为哪一个文件夹提供本地服务,默认为根文件夹
contentBase: './dist',
// inline:是否需要实时监听
inline: true
// port:指定端口号
// historyApiFallBack:在SPA页面中,指定依赖HTML5的history模式
}
}
配置package.json文件:
{
...,
"scripts": {
...,
// 配置webpack-dev-server的scripts,--open表示直接打开浏览器
"dev": "webpack-dev-server --open"
},
...
}
七、webpack配置文件的分离
base.config.js文件:公共配置文件,prod.config.js文件:生产时的配置文件,dev.config.js文件:开发时的配置文件,自己根据使用情况拆分,并将它们放入build文件夹。
安装webpack-merge,用于合并配置文件:
> npm install webpack-merge
配置prod.config.js文件和dev.config.js文件:
const webpeckMerge = require('webpack-merge')
const baseConfig = require('./base.config')
module.exports = webpeckMerge (baseConfig, {
... //原本配置文件module.exports中的内容
})
配置package.json文件:
{
...,
"scripts": {
...,
"build": "webpack --config ./build/prod.config.js"
"dev": "webpack-dev-server --open --config ./build/dev.config.js"
},
...
}
出现打包后文件位置错误问题,需修改base.config.js文件内容:
module.exports = {
...,
output: {
path: path.resolve(__dirname, '../dist'), //此处根据实际情况进行修改
...
},
...
}