Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack笔记 简单的webpack #14

Open
AfterThreeYears opened this issue Dec 3, 2018 · 0 comments
Open

webpack笔记 简单的webpack #14

AfterThreeYears opened this issue Dec 3, 2018 · 0 comments

Comments

@AfterThreeYears
Copy link
Owner

AfterThreeYears commented Dec 3, 2018

webpack流程

  1. Complier 对象代表了完整的webpack的环境配置。
  2. Complier.run() -> Compliation 对象代表了一次资源版本构建。
  3. Compilation 对象也提供了很多关键步骤的回调,带来了一次版本的chunk。
  4. Compilation.buildModule -> loader -> chunk。
  5. Parser -> Dependency (负责处理依赖)。
  6. Template自带的代码模板直接生成最后的解析结果。
  7. Compiler / Compilation都继承Tapable

优化点

  1. 通过dll构建公共包例如react redux
    1.1 通过new webpack.optimize.CommonsChunkPlugin提取公共代码,例如工具包,antd 详情
  2. 抽象runtime代码
  3. 使用import() 进行懒加载
  4. tree-sharking
  5. PurifyCSSPlugin 进行csstree-sharking
  6. 使用chunkHash
  7. 通过HtmlWebpackPlugin插入runtime代码,减少请求
  8. 开启多进程模式
  9. manifest
  10. 通过SpeedMeasurePlugin来观察优化情况
  11. 开启Scope Hoisting

简易的webpack

// 流程
// chunk -> module -> loader -> dependency -> template
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const ejs = require('ejs');
const entry = process.argv[2] || './index.js';
const output = './mywebpack-output.js';
const modules = [];

function styleLoader(source) {
  const styleTemplate = `const style = document.createElement('style');
  style.innerHTML = ${JSON.stringify(source).replace(/\\n/g, '')};
  document.head.appendChild(style);`
  return styleTemplate;
}
function getDep(result) {
  result.replace(/require\(['"](.+?)['"]\)/g, (...args) => {
    if (!args) return;
    const script = args[1];
    let content = fs.readFileSync(path.join('./src', script), 'utf-8');
    if (/\.css$/.test(script)) {
      content = styleLoader(content);
    }
    if (modules.find((d) => d.script === script)) {
      return;
    }
    modules.push({
      script,
      content,
    });
    getDep(content);
  });
}

const result = fs.readFileSync(path.join('./src', entry), 'utf-8');
getDep(result);

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

const outContent = ejs.render(template, {
  entry,
  result,
  modules,
});

// console.log(outContent);

fs.writeFileSync(path.join('./dist', output), outContent);

// 首先读取入口文件,然后对入口文件进行依赖解析,如果解析到有require函数的话,再次进行文件读取,返回内容,放入modules数组中备用,
// 然后把主入口文件首先用模板渲染完成以后,再去对modules数组,进行循环渲染
// 其中匹配文件的时候如果遇到了css文件,那么使用style loader进行处理




// (function main(modules) {
//   function require(moduleId) {
//     var module = {
// 			exports: {}
// 		};
//     modules[moduleId].call(module.exports, module, module.exports, require);
//     return module.exports;
//   }
//   require('./index.js');
// })({
//   './index.js': (() => {
//     eval("alert(1)")
//   })
// })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant