likes
comments
collection
share

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

作者站长头像
站长
· 阅读数 29

前言

众所周知我们在日常开发项目的过程中都会使用到webpack,vite等等这样的静态模块打包工具,那么他们的工作原理的流程是怎样的呢?在本文中将从一个小demo开始我们的webpack工作原理流程.

回顾webpack打包

我们使用webpack进行打包,就不得不提起webpack.config.js这样一个配置文件,这个配置文件的存在让webpack打包项目拥有着高度可配置性.

webpack.config.js中我们通过module.exports导出一个对象,在该对象中定义了一些该项目的配置.在该项目启动时,webpack会先读取webpack.config.js文件,根据该文件里面的配置信息来构建项目.

本文这个demo的目录如下

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

我们需要将文件main.js引入在index.html中执行,然而我们在main.js文件中是引入了add.js文件,这样就会有一个不同模块文件之间的引用的过程.这样会导致代码的可维护性,可读性不是很好,所以我们希望打包整合不同的模块文件保证各个模块文件之间正常的依赖关系.

那么这个打包过程是一个怎样的过程呢?我们先看到配置文件中的module.exports

配置文件介绍

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode:'development',
    entry:{
        main:'./src/main.js'
    },
    output:{
        path:path.resolve(__dirname, './dist'),
        filename:'js/chunk-[contenthash].js',
        clean:true
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./public/index.html',
            filename:'index.html',
            inject:'body'
        })
    ],
    module: {
        rules: [
          {
            test: /\.css$/i,
            //从右往左读
            use: ['style-loader', 'css-loader'],
          },
        ],
    }
}

mode:mode可以告诉webpack使用哪一种模式,一共有三个参数可以选择,development开发环境,production生产模式,none不会使用任何默认的优化选项,如果没有设置mode的值,那么webpack就会给mode的默认值设置成production.

entry:这里设置入口起点也就是整个项目的入口文件,默认值会是./src/index.js,当然我们也可以自己决定使用哪一个文件作为入口文件

output:输出配置,在这里我们需要设置webpack的输出内容放在哪里,且命名该输出文件. 这里我们是引入了node.js中的fs文件系统模块,添加的这个clear属性可以帮助我们清除旧文件,假设我们第一次生成了一个文件,当我们修改代码再一次执行让webpack进行构建,第一次生成的js文件就会被删除.我们这里文件命名也挺讲究的,使用的是hash值来命名chunk-[contenthash].js,每一次新生成的整合文件都会附带一个hash值.

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

plugins:是插件配置,这里我们可以使用一些插件来辅助我们工作,这里这个插件HtmlWebpackPlugin帮助我们引入js文件,因为我们每一次在这个项目中使用webpack构建,生成的这个js文件都会有一个hash值,也就意味着,我们在index.html文件中引入js文件都会是不一样的.所以我们使用HtmlWebpackPlugin帮助我们生成一个html文件,这个html文件会自动帮我们引入好这个js文件.

module:这个其实是webpack中的loader,在这里我们可以告诉webpack加载css文件.

所以总的来说webpack是先读取到入口文件,然后开始分析入口文件,此时如果读到需要去引入模块,就会先去引入模块,如果在读取引入模块所指的文件中也需要引入,那么依旧会去先读去引入模块,当引入模块读取完才会回头读取剩下的代码,其实这就是一个递归读取模块的所有依赖,然后生成一个ASt也就是抽象语法树,然后webpack会根据抽象语法树(AST)生成浏览器能运行的代码,如果浏览器无法运行该代码的版本,那么webpack就会让代码降级成为浏览器能读懂的代码.那么我们手搓一个是否可行呢?

手搓实现简单的webpack

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

这是我们这个手搓webpack的目录结构,由于代码可能会比较杂,这里我就简单说明一下几个文件,add.js里面写了一个加法,minus.js里面写了一个减法.那么在index.js中我们引入并调用了.现在我们将在index.html中引入index.js并在浏览器得到结果.

在文件bundle.js中使我们的核心文件,所有的逻辑都在这里实现.第一步我们是需要读取入口文件资源的,这里我们使用的是fs文件系统,这里我们打造了一个getModeleInfo函数用于获取获取模块

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

通过fs.readFileSync(file, 'utf8');获取到了我们入口文件的信息,然后就是需要分析模块,这我们就需要使用到@babel/parser这个模块,我们需要通过npm i来安装.这里我们设置的是模块化语法

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

此时这个ast其实是一个抽象语法树.在这个抽象语法树中就包含了依赖信息,所以我们下一步时需要去遍历这棵抽象语法树,人为地进行依赖收集,需要使用到的是@babel/traverse,同样也需要下载.

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

第一个参数是我们遍历的抽象语法树,第二个参数是我们需要遍历的部分,这里我们只需要遍历依赖关系部分就好了.这部分代码会将该依赖的路径变成一个完整的路径.

下一步就是进行代码降级,避免浏览器读不懂代码.使用的是@babel/core@babel/preset-env,在@babel/core存在一个transformFromAst()方法,第一个参数是抽象语法树,第二个参数为空,第三个参数表示降级到浏览器能读懂的版本.这里我们不用指具体的版本,直接使用@babel/preset-env,会读取到当前环境下对应的能执行的代码版本.

当我们获取完所有的模块后我们需要递归获取所有的依赖

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

这里我们拿到入口文件返回的模块信息,我们就遍历这个数组,检查这个模块的依赖文件是否存在下一级的依赖,存在就递归调用了.

最后一步就是处理require,因为windows环境下是没有require的. 这里bundle函数通过调用parseModules函数获取到所有的模块以及依赖关系,并将这些信息存储在对象depsGraph中,且创建一个立即执行函数.

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

引入的一些模块

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

现在我们去运行index.html,看看打印结果.

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

强大的打包工具webpack工作原理是怎样一个流程,我们一起来看看!!!前言 众所周知我们在日常开发项目的过程中都会使用

成功的实现了我们的目的.

本文到此就结束了,希望这些对大家有所帮助,谢谢大家阅读!!!

转载自:https://juejin.cn/post/7417847546321895465
评论
请登录