webpack详解

什么是Webpack?

官方解释:At its core, webpack is a static module bundler for modern JavaScript applications. (从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具。)核心就是:模块和打包

前端模块化

webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。而且不仅仅是JavaScript文件,CSS、图片、json文件等等在webpack中都可以被当做模块来使用。这就是webpack中模块化的概念。

打包就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。

webpack的安装

安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm

1
2
//查看node版本
node -v

全局安装webpack

1
npm install webpack@3.6.0 --save-dev

–save-dev是指开发时依赖,项目打包后不需要继续使用。

–save是指项目运行必须的依赖。

局部安装webpack

一个项目往往依赖特定的webpack版本,全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题。所以通常一个项目,都有自己局部的webpack。

  1. 项目中需要安装自己局部的webpack

    1
    npm install webpack@3.6.0 --save-dev
  1. 通过进入node_modules/.bin/webpack启动webpack打包

在终端直接执行webpack命令,使用的全局安装的webpack

当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack

准备工作

创建如下文件夹和文件

使用webpack的指令进行打包

1
webpack src/main.js dist/bundle.js

打包后会在dist文件下,生成一个bundle.js文件

bundle.js文件,是webpack处理了项目直接文件依赖后生成的一个js文件,我们只需要将这个js文件在index.html中引入即可。

webpack配置

入口和出口

如果每次使用webpack的命令都需要写上入口和出口作为参数,就非常麻烦,创建一个webpack.config.js文件可以将这两个参数写到配置中,在运行时,直接读取。

package.json中定义启动

package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。

首先,会寻找本地的node_modules/.bin路径中对应的命令。

如果没有找到,会去全局的环境变量中寻找。

执行build 指令

1
npm run build

loader的使用过程

步骤一:通过npm安装需要使用的loader

步骤二:在webpack.config.js中的modules关键字下进行配置

大部分loader都可以在webpack的官网中找到

[https://www.webpackjs.com]:

css文件处理

1.在src目录中,创建一个css文件,其中创建一个normal.css文件

2.在入口文件中引用:import css from “./css/normal.css”;

3.根据webpack官方文档进行安装和配置css-laoder

css-loader只负责加载css文件,但是并不负责将css具体样式嵌入到文档中。还需要一个style-loader帮助我们处理。

各种loader和webpack的对应版本在github中查看

less文件处理

1.安装相应的less-loader和less

1
npm install --save-dev less-loader less

2.添加一个rules选项,用于处理.less文件

1
2
3
4
5
6
7
8
9
10
rules: [{
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "less-loader" // compiles Less to CSS
}]
}]

图片文件处理

1.安装相应的url-loader

1
npm install --save-dev url-loader 

2.添加一个rules选项,用于处理图片文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//limit属性的作用,当图片小于8kb时,对图片进行base64编码
limit: 8192
}
}
]
}
]

3.大于8kb的图片,会通过file-loader进行处理,安装file-loader

1
npm install --save-dev file-loader 

4.再次打包,就会发现dist文件夹下多了一个图片文件

webpack自动帮助我们生成一个非常长的名字,是一个32位hash值,目的是防止名字重复。

改变图片名称,我们可以在options中添加上如下选项:

  • img:文件要打包到的文件夹
  • name:获取图片原来的名字,放在该位置
  • hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位
  • ext:使用图片原来的扩展名
1
2
3
4
5
options: {
//limit属性的作用,当图片小于8kb时,对图片进行base64编码
limit: 8192
name: 'img/[name].[hash:8].[ext]'
}

另外还需要改变图片路径

默认情况下,webpack会将生成的路径直接返回给使用者

但是,我们整个程序是打包在dist文件夹下的,所以这里我们需要在路径下再添加一个dist/

ES6语法处理

直接使用babel对应的loader就可以将ES6语法转换为ES5语法。

1
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

配置webpack.config.js文件

1
2
3
4
5
6
7
8
9
10
11
12
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
]

webpack配置Vue

一、引入Vuejs

1
npm install vue --save

修改webpack的配置

1
2
3
4
5
6
resolve: {
//alias:别名
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},

二、安装vue-loader和vue-template-compiler

1
npm install vue-loader  vue-template-compiler --save-dev

修改webpack.config.js的配置文件

1
2
3
4
{
test: /\.vue$/,
use: ['vue-loader']
}

plugin的使用

loader和plugin区别

  • loader主要用于转换某些类型的模块,它是一个转换器。
  • plugin是插件,它是对webpack本身的扩展,是一个扩展器。

plugin的使用过程:

  • 步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
  • 步骤二:在webpack.config.js中的plugins中配置插件。

添加版权的Plugin(BannerPlugin)

修改webpack.config.js的文件:

1
2
3
4
const webpack = require('webpack')
plugins: [
new webpack.BannerPlugin('最终版权归cjy所有'),
]

重新打包程序后可以查看bundle.js文件的头部,看到版权信息。

打包html的plugin(HtmlWebpackPlugin)

HtmlWebpackPlugin插件可以为我们做这些事情:

  1. 自动生成一个index.html文件(可以指定模板来生成)
  2. 将打包的js文件,自动通过script标签插入到body中

安装HtmlWebpackPlugin插件

1
npm install html-Webpack-Plugin --save-dev

修改webpack.config.js文件中plugins部分的内容如下:

1
2
3
4
5
6
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: 'index.html'
})
]
  • 这里的template表示根据什么模板来生成index.html
  • 另外,我们需要删除之前在output中添加的publicPath属性,否则插入的script标签中的src可能会有问题

js压缩的Plugin

在项目发布之前,我们必然需要对js等文件进行压缩处理

使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致

1
npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

修改webpack.config.js文件

1
2
3
4
const Uglifyjs = require('uglifyjs-webpack-plugin')
plugins: [
new Uglifyjs()
]

搭建本地服务器

​ webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

安装webpack-dev-server

1
npm install --save-dev webpack-dev-server@2.9.1

devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

  • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
  • port:端口号
  • inline:页面实时刷新
  • historyApiFallback:在SPA页面中,依赖HTML5的history模式

webpack.config.js文件配置修改如下:

1
2
3
4
devServer: {
contentBase: './dist',
inline: true
}

在package.json配置另外一个scripts:–open参数表示直接打开浏览器

1
"dev": "webpack-dev-server --open --config ./build/dev.config.js"

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!