2022-05-31

一.webpack打包基本原理

1.以入口文件单个模块为例

1.1获取模块内容

使用node.js的核心模块fs

// bundle.js

const fs = require('fs')

const getModuleInfo = file => {

    const body = fs.readFileSync(file, 'utf-8')

    console.log(body)

}

getModuleInfo('./src/index.js')

读出来的是字符串,可以用正则表达式提取import、export的内容以及路径名。

1.2分析模块内容

安装@babel/parser,把js文件的代码内容转换成js对象的形式,抽象语法树

1.3对模块内容做处理

遍历抽象语法树,将相对路径转为绝对路径;将ES6转化ES5

2.递归获取所有模块的信息

从入口模块开始,对每一个模块以及模块依赖的模块都调用getModuleInfo 进行分析,最终返回包含所有模块信息的对象

根据模块分析数据,生产浏览器运行的代码

手写loader

loader本质上是一个函数,会在我们加载一些文件时执行。

1.创建syncLoader.js

这个函数必须返回一个buffer或string

对于loader的编写,一定不要使用箭头函数,那样会改变this的指向。

// syncLoader.js

const loaderUtils = require('loader-utils')

module.exports = function (source) {

    const options = loaderUtils.getOptions(this)

    console.log(options)

    source += options.message

    // 可以传递更详细的信息

    this.callback(null, source)

}

2.配置webpack

const path = require('path')

module.exports = {

    mode: 'development',

    entry: {

        main: './src/index.js'

    },

    output: {

        path: path.resolve(__dirname, 'dist'),

        filename: '[name].js'

    },

    resolveLoader: {

        // loader路径查找顺序从左往右

        modules: ['node_modules', './']

    },

    module: {

        rules: [

            {

                test: /\.js$/,

                use: {

                  loader: 'syncLoader',

                  options: {

                    message: '1111'

                  }

                }

            }

        ]

    }

}

异步loader

const loaderUtils = require('loader-utils')

module.exports = function (source) {

    const options = loaderUtils.getOptions(this)

    const asyncfunc = this.async()

    setTimeout(() => {

        source += '走上人生颠覆'

        asyncfunc(null, res)

    }, 200)

}

你可能感兴趣的:(2022-05-31)