import被webpack编译成了啥?

import 被webpack 编译成了啥?

我们知道,webpack 打包过程如下:

  • 合并webpack.config.js和命令行传递的参数,形成最终的配置
  • 解析配置,得到entry入口
  • 读取入口文件内容,通过@babel/parse将入口内容(code)转换成ast
  • 通过@babel/traverse遍历ast得到模块的各个依赖
  • 通过@babel/core(实际的转换工作是由@babel/preset-env来完成的)将ast转换成es5 code
  • 通过循环伪递归的方式拿到所有模块的所有依赖并都转换成es5

那么,问题来了。

问题:import moduleName from 'xxModule’和import(‘xxModule’)经过webpack编译打包后最终变成了什么?在浏览器中是怎么运行的?

答案:

  • import经过webpack打包以后变成一些Map对象,key为模块路径,value为模块的可执行函数;
  • 当然其中的异步方法(import(‘xxModule’))比较特殊一些,它会单独打成一个包,采用动态加载的方式。
    具体过程:当用户触发其加载的动作时,会动态的在head标签中创建一个script标签,然后发送一个http请求,加载模块,模块加载完成以后自动执行其中的代码,主要的工作有两个,更改缓存中模块的状态,另一个就是执行模块代码。(webpack4)

没看懂?继续往下看解析

分析:

  1. 初始化项目

    在这里插入图片描述

    执行命令

    npm init -y
    npm i webpack webpack-cli -D
    

    webpack.config.js文件:

    const path = require('path')
    
    module.exports = {
      entry: './src/index.js',
      // 为了利于分析打包后的代码,这里选择开发模式
      mode: 'development',
      output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'main.js'
      }
    }
    

    src/index.js 文件:

    /**
     * 入口文件,引入 print 方法,并执行
     * 定义了一个 button 方法,为页面添加一个按钮,并为按钮设置了一个 onclick 事件,负责动态引入一个文件
     */
    import { print } from './num.js'
    
    print()
    
    function button () {
      const button = document.createElement('button')
      const text = document.createTextNode('click me')
      button.appendChild(text)
      button.onclick = e => import('./info.js').then(res => {
        console.log(res.log)
      })
      return button
    }
    
    document.body.appendChild(button())
    

    src/num.js 文件:

    export function print () {
      console.log('我是 num.js 的 print 方法')
    }
    

    src/num.js 文件:

    export const log = "log info"
    

打包

执行命令

npx webpack

在这里插入图片描述

会看到多了一个 dist 目录,且看输出结果,main.js是我们在webpack.config.js中配置的输出的文件名,但是src_info_js.main.js呢?这是什么????

模版文件

新建/dist/index.html文件,并引入打包后的main.js

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src = "./main.js"></script>
</body>
</html>

在浏览器打开 index.html

控制台输出如下:

在这里插入图片描述

nextwork 加载的资源如下:

在这里插入图片描述

当点击按钮后,src_info_js.main.js 文件被加载

在这里插入图片描述

分析打包后的源码

首先将源码折叠

(function (modules) {
  // xxxx
})({
  // xxx
})

这是一个自执行函数

函数参数

在这里插入图片描述


webpack将所有的import moduleName from 'xxModule’都变成了一个Map对象,key为文件路径,value为一个可执行的函数,而函数内容其实就是模块中导出的内容,当然,模块自己也被webpack做了一些处理,接着往下进行。

从打包后Map对象中能找到我们代码中的各个模块,以及模块的内容,但是也多了很多不属于我们编写的代码,比如以__webpack_require__开头的代码,这些又是什么呢?其实是webpack自定义的一些方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐