注意:篇幅很长,我在耐心写,也请读者耐心看。一直在更新,未完待续。。。
一直在看webpack的资料和视频,但是一直没总结,总觉得一知半解的。所以在此想从头开始总结一篇webpack的配置和并且其中的原理和打包机制也会进行介绍,在提升自己的认知的过程中也希望能帮到小白或者对webpack了解不够系统的童鞋。毕竟webpack5就要问世了,webpack4你还不会配置,作为一个前端工程湿你还想咋样???
基本打包步骤
先不和全家桶项目挂钩,我们先来学习一下打包命令的使用。
第一步,在终端创建文件夹(路径自己决定)
mkdir test01
cd test01
npm init
初始化完项目以后,我们可以看到test01文件夹里面多了一个package.json文件。
第二步,在文件夹下安装webpack依赖
npm install webpack --save-dev
或者
npm install webpack -D
这里的--save -dev就不说为啥了,自己去百度。可以参考这篇博客https://blog.csdn.net/qq_30378229/article/details/78463930
我们先来执行一下打包。先来说一下webpack配置文件里默认的入口文件是src目录下的index.js文件,输出目录默认是dist文件夹main.js文件。
我们在test01文件夹下面创建src文件夹,在src文件夹下创建index.js和hello.js
index.js代码如下:
import hello from './hello';
document.write(hello())
hello.js代码如下:
export default function hello(){
return 'Hello webpack!!!'
}
第三步,在文件夹目录下执行命令
./node_modules/.bin/webpack
此时会报错,说没有安装webpack-cli工具,这是因为webpack4.x里面将webpack-cli单独分离出来了。所以我们执行
npm i webpack-cli -D
安装这个依赖后,就可以执行./node_modules/.bin/webpack这个命令了。
可以在终端看到这些信息:
Hash: d5deb2b4a7096275847d
Version: webpack 4.32.2
Time: 255ms
Built at: 2019-06-03 23:16:33
Asset Size Chunks Chunk Names
main.js 986 bytes 0 [emitted] main
Entrypoint main = main.js
[0] ./src/index.js + 1 modules 114 bytes {0} [built]
| ./src/index.js 52 bytes [built]
| ./src/hello.js 62 bytes [built]
然后我们可以看到在test01下面生成了一个dist文件夹,里面有一个main.js文件。
此时我们在dist文件夹下面添加一个index.html文件,将生成的main.js文件引入进去。用浏览器打开index.js文件可以看到在浏览器里面输出了Hello wepack!!!
我们当然可以写webpack配置文件来进行打包,所以我们此时在test01文件夹下创建文件:webpack.config.js代码如下:
const path = require('path');
module.exports={
entry:'./src/index.js',
output:path.resolve(__dirname,'/dist'),
mode:'production',
}
入口和出口
之前有提到过默认的入口是根目录下src/index.js,默认出口是根目录下的dist/main.js。那么这里的entry就是来自定义入口文件。单入口文件直接写字符串,多入口文件就要写成一个对象,举个栗子:
//单入口
module.exports = {
entry: './src/index.js'
}
//多入口
module.exports = {
entry: {
app: './src/app.js',
adminApp: './src/adminApp.js'
}
}
多入口打包入口对象属性写的是啥,打包出来的js文件名就是啥,如以上写法打包出来的文件就是app.js和adminApp.js文件。接下来我们继续,webpack4.x里面加入了mode,有三个值:none、development和production。其意义不言而喻。production模式在打包的时候,webpack会自动的将代码进行一些处理,如压缩代码等。开发者模式则是能够更好的进行调试。在这里我们暂时先写成生产模式。所以接下来就是要在package.json里面加入script。代码如下:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
我们清理一下之前的dist目录,然后在终端执行npm run build 命令,我们可以看到也可以将文件进行打包到dist目录里。
loader
接下来介绍各种loader以及它的写法,loader是用来解析各种资源,下面来说一下常用的loader和写法。在webpack打包过程当中,遇到什么样格式的文件就启动什么样的loader去进行处理。
babel-loader
这是处理JS的loader。那么如何将js中的ES6语法转换成各个浏览器支持的ES5语法呢?
我们会用到babel这个module。在这里我们只需要安装@babel/core,@babel/preset-env 和 babel-loader就可以将ES6语法进行转换。
首先我们进行安装。输入以下命令:
npm i @babel/core @babel/preset-env babel-loader -D
写法:
module:{
rules:[
{
test:/\.js$/,
use:'babel-loader'
}
]
}
在这里我们要配置一个.babelrc文件,webpack在打包js文件的时候,会自动加载这个文件里面的规则。那么这个文件在这里只需要配置以下内容。具体详细的配置以后再给大家讲解。
{
'presets':[
"@babel/preset-env"
]
}
上面是解析ES6的相关配置。
安装完成后我们可以在文件夹书写ES6语法的语句。然后进行打包,可以发现打包成功。
那么除了解析js的ES6语法以外如果我们在工程中书写的是JSX文件或者是在js文件里使用的jsx语法该如何进行配置呢?举个栗子。假设我我们在这里使用的是react框架进行项目开发。那么我们首先是要将基本的react框架的module进行安装。
npm i react react-dom --save
react这个module是用来创建react组件的,react-dom的module可以将react的组件挂载到相应的HTML节点上的。
但是这还不够,因为并没有对jsx语法进行解析,我们需要这个@babel/preset-react。所以安装起来。
npm i @babel/preset-react -D
安装好以后我们需要在.babelrc文件里面加上一句就可以了
{
'presets':[
"@babel/preset-env",
"@babel/preset-react"
]
}
另外要解析jsx文件的话,需要修改一下正则表达式test:
module:{
rules:[
{
test:/\.(js||jsx)$/,
use:'babel-loader'
}
]
}
接下来就是要创建jsx文件或者在js文件中写组件咯。具体如何写,我就不在这里距离说明了,写完以后,运行命令可以看到打包并没出错,说明打包成功。
file-loader
用途:用来解析字体,各种格式的图片
写法:
module:{
rules:[
{
test:/\.(woff|woff2|eot|ttf|otf)$/,
use:[
'file-loader'
]
},
{
test:/\.(png|jpg|jpeg|svg|gif)$/,
use:[
'file-loader'
]
}
]
}
url-loader:可以用来解析字体和各种各种的图片。但是还有另外一个优点就是对一些小的图片可以解析成base64的。在里面有一个选项可以进行配置,在options{}配置limit,单位是字节。
写法:
module:{
rules:[
{
test:/\.(woff|woff2|eot|ttf|otf)$/,
use:[
'file-loader'
]
},
{
test:/\.(png|jpg|jpeg|svg|gif)$/,
use:[{
loader:'url-loader',
options:{
limit:10240
}
}]
}
]
}
接下来我们来看一下在Dev环境下进行开发的时候,webpack文件监听的原理。
文件监听原理
用过轮询来判断文件的最后编辑时间是否变化。某文件a最后编辑时间发生了变化,表示发生了变化,但是并不会立刻告诉监听者,而是先缓存起来,等待aggregateTimeout之后再去执行。
两种方式:
1,webpack --watch,不能自动刷新。
2,webpack-dev-sever
我们先来看一下关于watch的配置.
module.export = {
watch:true,//默认false,也就是不开启的
//下面的配置项,只有在watch开启的时候才有效
watchOptions:{
ignored:/node_modules/,//正则匹配不监听的文件夹,默认为空
aggregateTimeout:300,//监听到文件的最后编辑时间变化等待300ms后去执行,默认300ms
poll:1000,//判断文件是否发生变化是通过不停的轮询系统指定的文件有没有变化实现的,默认1000ms轮询一次
}
}
网友评论