书写简单的webpack

223 阅读1分钟
#! /usr/bin/env node
// 这个文件时描述如何打包
// let entry = '@/src/index.js'
let entry = './src/index.js' // 入口文件
let output = './dist/main.js' // 出口文件
let path = require('path')
// let entry = path.join(__dirname,'../../src/index.js');
// let output = path.join(__dirname,'../../dist/main.js')

let fs = require('fs')
let script = fs.readFileSync(entry, 'utf-8')
let modules = []

// loader
let styleLoader = function(source) { // source 代表的是样式文件中的内容
  return `
    let style = document.createElement('style')
    style.innerHtml = ${JSON.stringify(source).replace(/\\r\\n/g, '')}
    document.head.appenChild(style)
  `
}

// 处理依赖关系
script = script.replace(/require\(['"](.+?)['"]\)/g, function() {
  console.log(script)
  let name = path.join('./src', arguments[1]) // a.js
  let content = fs.readFileSync(name, 'utf-8')
  if (/\.css$/.test(name)) {
    content = styleLoader(content)
  }
  modules.push({
    name, content
  })
  return `require('${name}')`
})
let ejs = require('ejs')
// let name = 100
// console.log(ejs.render('<a><%-name%></a>',{name}))

let template = `
(function(modules) { // webpackBootstrap
  function require(moduleId) {
    var module = modules[moduleId] = {
      exports: {}
    };
    modules[moduleId].call(module.exports, module, module.exports, require);
    return module.exports;
  }
  return require("<%-entry%>")
})
({
 "<%-entry%>":
   (function(module, exports, require) {
     eval(\`<%-script%>\`);
   })
   <%for(let i =0; i< modules.length; i++) {
    let module = modules[i]; %>,
    "<%-module.name%>":
    (function(module, exports, require) {
      eval(\`<%-module.content%>\`);
    })
   <%}%>
});
`

let result = ejs.render(template, {
  entry,
  script,
  modules
})
// result 为替换后的结果,最后写到 output中

fs.readFileSync(output, result)
console.log('编译成功')