Webpack - Bundler编写

Webpack - Bundler编写

word.js

定义常量导出

export const word = 'hello';

message.js

通过es6 import语法引入,修改后再次到处

import { word } from './word.js';
const message = `say ${word}`;
export default message;

index.js

浏览器不识别该语法,无法正确运行,因此需要webpack替我们打包

import { word } from './word.js';
const message = `say ${word}`;
export default message;

bundler.js - 打包工具实现

引入node相关依赖

// 帮助获取文件信息
const fs = require('fs')
const path = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const babel = require('@babel/core')

分析入口文件

const moduleAnalyser = (filename) => {
  // 读出文件内容 - 转化成对象(抽象语法树ast)
  const content = fs.readFileSync(filename, 'utf-8')
  const ast = parser.parse(content, {
    sourceType: 'module'
  })

  // 找到import语句,分析依赖内容,依赖封装成对象(dependencies)
  // dependencies存储文件所有依赖关系,键值对形式,键 - 依赖文件的相对路径,值 - 依赖文件的绝对路径
  const dependencies = {}
  traverse(ast, {
    ImportDeclaration ({ node }) {
      const dirname = path.dirname(filename)
      const newFile = './' + path.join(dirname, node.source.value)
      dependencies[node.source.value] = newFile
    }
  })

  // 对代码进行编译,es6 -> 浏览器可识别
  const {code}  = babel.transformFromAst(ast, null, {
    presets: ["@babel/preset-env"]
  })

  // 返回入口文件名字、依赖关系、被编译过后的代码
  return {
    filename,
    dependencies,
    code
  }
}

依赖图谱

const makeDependenciesGraph = (entry) => {
  // 所有模块通过moduleAnalyser进行分析,存储数组(graphArray)
  const entryModule = moduleAnalyser(entry)
  const graphArray = [entryModule]
  for (let i = 0; i < graphArray.length; i++) {
    const item = graphArray[i]
    const { dependencies } = item
    if (dependencies) {
      for (let j in dependencies) {
        graphArray.push(
          moduleAnalyser(dependencies[j])
        )
      }
    }
  }
  // 将数组进行处理,转换成对象进行return
  const graph = {}
  graphArray.forEach(item => {
    graph[item.filename] = {
      dependencies: item.dependencies,
      code: item.code
    }
  })
  return graph
}

const generateCode = (entry) => {
  const graph = JSON.stringify(makeDependenciesGraph(entry))

  return `
    (function(graph){
      function require(module) {
        function localRequire(relativePath) {
          return require(graph[module].dependencies[relativePath])
        }
        var exports = {};
        (function(require, exports, code){
          eval(code)
        })(localRequire, exports, graph[module].code)
        return exports
      };
      require('${entry}')
    })(${graph})
  `
}

const code = generateCode('./src/index.js')
console.log(code)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值