前言
之前都是应用,没有零碎的残缺的好好学习过一遍webpack的原理,趁现在工作有些闲空,整顿下。增强下记忆
什么是webpack?
不想放webpack官网那张图,感觉都快看吐了。
算了还是斗争把,要不然不好说分明…..
官网的哈,看能看出的来,那持续了~~
分为三个局部
左侧:
写我的项目的源代码,源文件
左侧有一个入口,最下面的.js
一个一个的方格能够了解成一个一个的模块,因为webpack是基于node的,所以能够用模块的概念来辨别文件。箭头的示意
➡️一个模块能够依赖多个模块
箭头➡️示意他们之间的依赖关系
左侧会有很多,后缀的文件是浏览器无奈辨认的。例如:.sass .hbs .cjs
所以须要通过webpack 来构建一次打包
通过webpack的构建
右侧:
输入浏览器能够正确执行的文件,资源
咱们还能够利用webpack来压缩 js 、压缩图片 。
所以webpack就是一个模块打包器
webpack装置
分为两种装置形式
- 我的项目装置
(举荐)
有些我的项目可能很老,依赖的webpack的版本比拟低。
最新的是webpack4.X; webpack5.x还没有公布
- 全局装置
如果是全局装置,版本会固定化。如果是去批改来的版本会抵触,依赖抵触等。所以依据我的项目来装置webpack,会好些。
装置:
webpacl4.x之后,这两个必须要都装置,webpack和 webpack-cli;不倡议离开装。
创立我的项目之后,现须要npm init
一下,之后在装置。初始化一下。这个大家应该都晓得。
npm install webpack webpack-cli -D
webpack启动
webpack4.0公布的时候,有说,反对零配置启动。后果发现,哈哈哈哈哈哈哈哈~~~没啥用。根本用不到我的项目中。
咱们来看下零配置:
装置好webpack之后,咱们来创立一个入口文件,index.js
零配置 :
默认入口:
./src/index.js
如果没有src 上面的index.js 打包是不胜利的。
默认进口:输入的目录是./dist
,输入的资源名称:main.js
接下来,启动webpack,启动形式有两种。
第一种启动形式:
npx webpack
为啥用npx启动我的项目
npm5.2版本,就自带npx这个性能;
当初咱们启动的整个我的项目webpack是部分装置的
如果全局没有装置webpack,全局执行webpack
就会报错,command not found
。它会去全局环境变量中去寻找。
通过npx 启动webpack,它会在以后我的项目下的node_modules/.bin
目录去找它的软连贯,在.bin
目录下找到webpack,去启动它。
来看下,打包好外面都显示了啥?
- 构建的哈希版本
Hash: 096bb4bcb72f81514554
- 执行构建的webpack版本
Version: webpack 4.44.1
- 执行构建的时长
Time: 217ms
- 结构的内容是什么?
// 输入的资源叫main.js
// 这个资源是958 bytes
// Chunks 是为 0
Built at: 2020-08-25 14:45:08
Asset Size Chunks Chunk Names
main.js 958 bytes 0 [emitted] main
// 这块示意 输入的main.js,是依据./src/index.js文件built而来的
Entrypoint main = main.js
[0] ./src/index.js 29 bytes {0} [built]
- 正告内容
本人百度吧,好吗? 用我小学的英语水平大略就是:环境没有设置:就是生产环境和开发环境没设置。会走一个默认的值,默认值是production(生产模式);
生产模式下的代码是进行压缩的,当初能够看下,main.js
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
测试打包好的main.js;是否能够应用
在dist外面,手动创立一个index.html,而后手动引入main.js;
dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
第二种启动形式:
在package.json,的scripts中,增加启动命令
"scripts": {
"dev": "webpack"
},
之后执行
npm run dev
成果和下面是一样的,就不进行在进行演示了。
当咱们在scripts中去定定义了执行命令dev,执行webpack;是从本地的
node_modules/.bin
目录的软连贯去找webpack
webpack配置文件,自定义配置文件
在根目录下创立,
webpack.config.js
webpack.config.js
就是webpack的自定义配置文件
当咱们执行npx webpack
首先会去我的项目上来查找 是否有webpack.config.js
,这个配置文件;如果没有会走默认配置;如果存在,就会依照webpack.config.js
配置外面的内容去进行构建
webpack.config.js
webpack是基于node 的,所以能够间接导出模块
module.exports={
entry(入口):(有三种类型)
output(进口): {
// 指定输出资源寄存目录,地位
// path 必须是绝对路径
path:,
//输入文件名
filename:,
}
// 刚刚报的正告,就是这个值没有设置。
mode: 构建模式
}
webpack.config.js
const path =require('path')
module.exports={
entry:'./src/index.js',
output:{
path:path.resolve(__dirname,'./build'),
filename:'main.js'
},
// 开发模式
mode:'development'
}
npx webpack
目录新创建了一个build;main.js中的文件没有被压缩,开发模式下,文件不会被打包。
main.js 文件内容分析
main中是一个自执行的闭包函数
//行参 modules 所有的模块
(funcition(){modules})()
等下,我在创立个依赖js。为了不便看这个modules外面的内容。
modules是什么?
//modules 是一个对象,这个对象记录了,从入口模块登程,以及依赖模块的信息
来看下,在src/index.js中的内容
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _a_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a.js */ \"./src/a.js\");\n\nconsole.log('hello webpack'+_a_js__WEBPACK_IMPORTED_MODULE_0__[\"str\"]);\n\n//# sourceURL=webpack:///./src/index.js?");
/***/ })
引入a.js的形式改为了
__webpack_require_
通过webpack构建,对内容进行了一层解决,模块化语句也进行了一次解决__webpack_require_
在自执行函数中定义了这个办法的执行。
(先简略阐明下,前面会写具体的文档)
持续webpack配置文件;比方咱们在Vue cli工具创立的文件;所以咱们能够本人去定义webpack配置文件的名称,能够不叫webpack.config.js
;默认是走这个文件;
比方在根目录下新建一个,webpack.ohh.js
;那如何让webpack走这个配置文件呢,
须要在package.js
中
// --config 用这个--config来进行匹配
"scripts":{
"dev": "webpack --config ./webpack.ohh.js"
}
执行npm run dev
进行打包
webpack外围概念
- enrty:webpack执行构建的入口,默认是
./src/index.js
;
看官网那个图,就能看进去,须要一个js文件入口。当然这个文件入口也是能够批改的。
创立一个webpack.config.js,entry 就能够进行批改。
- output: 配置资源输入的地位和名称,
打包好的文件放在什么地位,叫什么名字
- mode:打包构建模式,有开发模式和生产模式两种。
development:开发模式,不压缩代码,有利于查找谬误
productiont:生产模式,公布到线上的代码,代码会被压缩
- chunk:代码片段,由入口模块文件与依赖模块的内容生成的。
- module:模块,webpack基于nodeJs,有所有皆模块的概念
在刚刚咱们打包的 a.js or index.js ;或者前面会去增加的 index.css,图片等,都能够成为模块
bundle: 打包输入到资源目录的文件,构建胜利后的输入文件
顺一顺~~~~
bundle chunk module,三者的关系:
SPA 我的项目 一个单页面利用,只会有一个bundle 文件;
MPA 我的项目 多页面利用,就会有多页面的bundle文件;比方index.js 和login.js
下面放了很多都是跑的SPA 单页面的利用;来看一个多页面MPA的。
首先是配置:
webpack.ohh.js
const path = require('path')
// 多入口
module.exports={
entry:{
index:'./src/index.js',
login:'./src/login.js'
},
output:{
path:path.resolve(__dirname, 'ohh'),
filename:'[name].js'
},
mode:'development'
}
一个bundle 文件,对应一个chunk外面会有多个片段
MPA 多页面利用,才会存在多个chunks;
SPA 单页面利用,只有一个入口,一个chunk,(然而可能会有多个片段组成:比方index.js中引入了a.js;那么chunk就有两个片段:一个是index、一个是a文件;);
**一个chunk对应一个entry
一个entry对应多个module**
- loader:模块转换;webpack默认只反对js模块,json模块。
css模块,和图片模块都不反对。就须要用到loader,
比方:src/index.css
body{ background: pink; }
src/index.js
引入 css// a.js // export const str='这是ajs'; import {str} from './a.js' import css from './index.css'; console.log('hello webpack'+str);
须要去配置loader
在配置文件,当然你也能够额写在webpack.config.js中。
创立一个module,写入加载规定
webpack.ohh.jsconst path = require('path') // 多入口 module.exports={ entry:{ index:'./src/index.js', login:'./src/login.js' }, output:{ path:path.resolve(__dirname, 'ohh'), filename:'[name].js' }, mode:'development', module:{ // 模块 rules:[ // 规定 { test: /\.css$/, use: "css-loader" }, ] } }
进行装置 css-loader
npm install css-loader -D
之后来跑一下我的项目:
npm run dev
看一下打包后果
没有报错 也没有显示,因为:
css-loader 的作用十分的繁多,只是让咱们的webpack晓得了,如何去解决css的语法,如何让css语法以字符串的形式,放到bundle文件外面去。否则就会报错,接下来要做的是,将这段代码提取进去放到html中。
npm install style-loader -D
style-loader 的作用:
将css提取进去,并且在html的头部,动静的生成style标签,将css放到外面去。
这时,还须要去批改下配置文件的module
webpack的配置文件批改;module:{ rules:[ { test:/\.css$/, use:["style-loader", "css-loader"] } ] }
增加一个style-loader
loader的自行程序,user:[];执行程序是从后往前的,所以先要把css解析进去,当前再用style-loader,生成style标签,将css内容放进去。【从右到左】
- 装置完了style-loader
- 配置文件批改了css文件的匹配规定
- 执行 npm run dev,查看页面加载状况
- 在打包好的文件中,【本人 创立】创立一个index.html;这样能够看到成果
浏览器关上这个index.html
展现胜利~~~~~!耶✌️
- 论断:
css-loader和style-loader须要配合来应用
- 为什么css-loader性能繁多,为什么要配合style-loader 才失效?
因为 自定义loader规定,一个loader只做一件事件。
style-loader的性能也很繁多,把款式放在一个动静生成的style标签外面。所以不会在本地打包的html文件中显示进去,是通过js动静生成的。所以引入js就能够。
如果像将css解决成独自的文件,而不是在页面创立一个style标签的模式放在html外面。那就不能用style-loader;
index.less的文件,咱们就有须要去加新的匹配规定,[“style-loader”,”css-loader”,”less-loader”]
- plugin:webpack 的一个性能扩大
举例: 像咱们刚刚手动去创立的index.html
如果咱们想要看到成果就须要,在打包我的文件夹中去手动创立index.html;十分的繁琐,那么如何解决呢?这个时候利用plugin;相当于webpack 的一个性能扩大。【官网中-右上角导航就有plugin,找一个适合的进行应用】
接下来,以如何主动创立index.html 来进行发展plugin的应用探讨先装置:
npm install html-webpack-plugin -D
- 配置webpack默认项:
webpack.config.js
const path =require('path')
// 这里导入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin')
// 单入口
module.exports={
entry:'./src/index.js',
output:{
path:path.resolve(__dirname,'./build'),
filename:'main.js'
},
// 开发模式
mode:'development',
module:{
rules:[
{
test:/.css$/,
use:['style-loader','css-loader']
}
]
},
plugins:[
new htmlWebpackPlugin({ // plugin的应用,先new一下
template:'./src/index.html', // 模板文件
filename:'index.html' //倒出的文件名
})
]
}
因为是在默认文件配置,所以跑起来,须要执行
npx webpack
成果如下:
这样就打包胜利了,那么间接用浏览器关上index.html
就能够看到成果了。并不在截图,因为和下面那个图片展现是一样的。就换成了主动生成html而已,仅此而已。
持续~~~~~(为什么要总结原理,我越写饿了,惆怅)为了保障每次创立进去的build,打包文件都是全新的,而且不存在冗余的文件,比如说,当咱们批改了一下 plugins中的
new htmlWebpackPlugin中的打包目录地址的配置:
filename:’html/ohh.html’
那么上次打包在根目录下的html并不会删除,就冗余了呗。
咱们就须要用到plugin来进行配置
先装置:npm install clean-webpack-plugin -D
应用,都是一样的
const {CleanWebpackPlugin} = require('clean-webpack-plugin') // 在pulugins中new一 plugins:[ new htmlWebpackPlugin({ // plugin的应用,先new一下 template:'./src/index.html', // 模板文件 filename:'index.html' //倒出的文件名 }), new CleanWebpackPlugin() ]
- 引入css文件而不是写在style标签外面,把款式抽离成独立的文件
首先装置plugin
npm install mini-css-extract-plugin -D
批改webpack的配置文件
- 引入plugin
plugins:[ new miniCssExtractPlugin({ filename:'css/index.css' }) ]
- 批改css文件的模块匹配规定和渲染形式
module:{ rules:[ { test:/.css$/, use:[miniCssExtractPlugin.loader,'css-loader'] } ] },
基本原理就差不多顺明确了。总结下
总结
webpack.config.js: webpack配置文件
基本概念
- entry:webpack执行构建工作的入口文件
- output:执行构建后,资源配置的输入地位和名称
- module: 模块
- chunk:入口文件和依赖模块组合,通过webpack构建成生的一段代码片段
- bundle: webpack构建实现够后输入的文件
- loader: 模块转化,让webpack能够反对转化更多的模块类型
- plugin:插件,让webpack性能更弱小
- modle: 打包构建模式,开发模式or生产模式
外围配置
- enrty:String|[]|{}
[] : 单页面利用
{}: 能够SPA or MPA。多入口对应多进口文件
- output:{path:,filename:“”}
path:必须是绝对路径
filename 能够应用占位符 [name] [hash]等
- mode:String
参数:“production” “development” “node”
- module :{}
{rules:[]}
- plugins : []
-
- *
webpack的学习,其实就是各种plugin和module的应用,用多了就写的顺了,所以次要的还是根底概念要分明,所以才独自拿进去进行一个梳理,鄙人见解哈。
发表回复