黑马程序员技术交流社区
标题: 长沙黑马精品公开课:模块化打包神器webpack [打印本页]
作者: 长沙-小知姐姐 时间: 2020-4-28 15:43
标题: 长沙黑马精品公开课:模块化打包神器webpack
本帖最后由 长沙-小知姐姐 于 2020-4-28 15:44 编辑
需要视频笔记源码的朋友可以回帖获取网盘密码(如失效请联系vx:csheima7)
https://pan.baidu.com/s/1J2QCSy1d7lbQh4uFjAKG-w
[hide=d100]jj4w[/hide]
###1.webpack的概念
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
通俗的来说,webpack就是一个打包构建工具,将各种各样的资源整合打包到一起,形成一个最终的完整项目。
###2.webpack的基本配置
####A.安装webpack
npm install webpack webpack-cli -D
####B.在项目目录中创建webpack.config.js文件用来配置webpack
在配置文件中可以配置开发模式和发布模式两种,如下:
module.exports = {
mode:"development"//可以设置为development(开发模式),production(发布模式)
}
也可以在运行webpack命令时,添加参数设置模式,如下:
webpack --mode=development
####C.在webpack.config.js文件中通过entry和output来设置入口和出口
```
const path = require("path");
module.exports = {
mode:"development",
//设置入口文件路径
entry: path.join(__dirname,"./src/js/index.js"),
//设置出口文件
output:{
//设置路径
path:path.join(__dirname,"./dist"),
//设置文件名
filename:"bundle.js"
}
}
```
补充:配置多入口和多出口
```
const path = require("path");
module.exports = {
mode:"development",
//设置入口文件路径
entry: {
"one":path.join(__dirname,"./src/js/one.js"),
"two":path.join(__dirname,"./src/js/one.js")
},
//设置出口文件
output:{
//设置路径
path:path.join(__dirname,"./dist"),
//设置文件名
filename:"[name].js"
}
}
```
####D.使用webpack-dev-server自动打包运行项目
第一步,安装webpack-dev-server,安装html-webpack-plugin
npm install webpack-dev-server -D
npm install html-webpack-plugin -D
第二步,修改package.json文件,配置运行指令
在package.json文件中添加或修改scripts节点,添加一个dev指令
"scripts":{
"dev":"webpack-dev-server --open --host 127.0.0.1 --port 9999"
}
第三步,在webpack.config.js文件中添加html-webpack-plugin插件进行项目预览
```
const HtmlWebpackPlugin = require("html-webpack-plugin");
//创建对象
const htmlPlugin = new HtmlWebpackPlugin({
//设置生成预览页面的模板文件
template:"./src/index.html",
//设置生成的预览页面名称
filename:"index.html"
})
module.exports = {
mode:"development",
//设置入口文件路径
entry: path.join(__dirname,"./src/js/index.js"),
//设置出口文件
output:{
//设置路径
path:path.join(__dirname,"./dist"),
//设置文件名
filename:"index.js"
},
// 使用plugins数组添加webpack需要使用的插件
plugins:[ htmlPlugin ]
}
```
注意:
无论是修改了package.json还是修改了webpack.config.js,请重启webpack-dev-serve才会让修改的内容生效。
###3.使用加载器预处理文件
加载器loader可以对模块的源代码进行转换。当我们使用import去导入一个文件的时候,加载器会对这个文件进行预处理和转换。
它可以把文件从不同的语言(比如typescript,高级JS语法等)转换成javascript,也可以将图片转换为data URL,甚至可以处理和转换css文件。
一句话,webpack本身只是一个构建工具,它一般只能识别js文件,如果想要让他识别和处理其他类型的文件,我们就需要给他添加功能(加载器)
比如说我们可以安装css的加载器,用来处理css样式,为此我们需要安装css-loader与style-loader,如下:
npm install style-loader css-loader -D
加载器的配置使用方式有三种:
A.使用配置文件
在webpack.config.js文件中可以通过module.rules配置加载器,如下
```
module.exports = {
mode:"development",
//设置入口文件路径
entry: path.join(__dirname,"./src/js/index.js"),
//设置出口文件
output:{
//设置路径
path:path.join(__dirname,"./dist"),
//设置文件名
filename:"index.js"
},
// 通过module.rules配置加载器
module:{
rules:[
//rules是一个数组,可以用来配置多个加载器
//加载器的执行顺序是反向的,也就是说先执行css-load,再执行style-loader
{ test:/\.css$/, use: ['style-loader','css-loader'] }
}
}
```
B.使用内联语法
就是编写js代码去引入加载器,使用!隔开多个加载器,使用?拼接参数
?后面的modules表示的是打开CSS Modules功能,modules后面跟着的是需要引入并处理的index.css文件路径
import Styles from 'style-loader!css-loader?modules!../css/index.css';
C.在命令行中使用加载器
webpack --module-bind 'css=style-loader!css-loader'
小结:
B形式会导致导入解析的代码过多,C形式会导致命令的参数过多。
所以一般推荐使用A形式,在配置文件中配置,修改和定位都会更加简单。
###4.自定义loader加载器
Webpack中loader是一个CommonJs风格的函数,接收输入的源码,通过同步或异步的方式替换源码后进行输出。
基本形式如下:
module.exports = function(source) {
//source是源码
return source.replace(/console/g, '//console')
}
然后需要在webpack.config.js中配置自定义loader
###5.webpack插件
插件是 webpack中一个非常重要的功能。插件目的在于解决 loader 无法实现的其他事
自定义插件的步骤:
A.创建一个函数
function myPlugin(){
}
B.给函数扩展一个apply方法
//注意,定义的函数不能写作箭头函数形式,否则函数中的this指向将会出错
myPlugin.prototype.apply = function( compiler ){
// compiler是一个对象,包含webpack的所有配置信息,在启动时被初始化,包括entry、output、loaders等配置,这个对象在启动Webpack时被实例化,而且是全局唯一的。Plugin可以通过该对象获取到Webpack的配置信息进行处理
// compilation Compilation对象可以理解编译对象,包含了模块、依赖、文件等信息,每修改一次文件都会产生一个新的Compilation对象,Plugin可以访问到本次编译过程中的模块、依赖、文件内容等信息
compiler.plugin('compile', function (compilationParams) {
console.log(compilationParams)
console.log('webpack 编译器开始编译...-----')
})
}
C.指定webpack的事件钩子
常见的钩子如下:
| 钩子 | 说明 | 参数 | 类型 |
| ------------ | ----------------- | ----------------- | ---- |
| afterPlugins | 启动一次新的编译 | compiler | 同步 |
| compile | 创建compilation对象之前 | compilationParams | 同步 |
| compilation | compilation对象创建完成 | compilation | 同步 |
| emit | 资源生成完成,输出之前 | compilation | 异步 |
| afterEmit | 资源输出到目录完成 | compilation | 异步 |
| done | 完成编译 stats | | 同步 |
我们可以使用Tabable暴露的tap,tapAsync和tapPromise方法来调用调用上面的钩子,如下
compiler.hooks.compile.tap('myPlugin', params => {
console.log('我是同步钩子')
});
compiler.hooks.emit.tapAsync('MyWebpackPlugin', (compilation, callback) => {
setTimeout(()=>{
console.log('文件列表', Object.keys(compilation.assets).join(','));
callback();
}, 1000);
});
具体的使用案例形式为:
function myPlugin(){
}
myPlugin.prototype.apply = function( compiler ){
compiler.hooks.emit.tapAsync('MyWebpackPlugin', (compilation, callback) => {
// compilation.chunks存放了代码块列表
compilation.chunks.forEach(chunk => {
// chunk包含多个模块,通过chunk.modulesIterable可以遍历模块列表
for(const module of chunk.modulesIterable) {
// module包含多个依赖,通过module.dependencies进行遍历
module.dependencies.forEach(dependency => {
console.log(dependency);
});
}
});
callback();
});
}
作者: unde²⁰²⁰ 时间: 2020-5-4 08:14
66666666666666666666666666666666666666
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |