This is the 122nd original article without water, if you want to get more original articles, please search our official account to follow us. This article was first published in the cloud blog: Webpack Principle – how to implement code packaging

preface

Webpack is all too familiar as a front-end siege lion. Webpack all resources (JS, TS, JSX, images, fonts, CSS, etc.) into dependencies so you can use them as needed by referencing dependencies. Webpack is very good to complete the front-end translation of a variety of file resources, analysis of complex module dependent work, and we can also customize the loader, free to load our own resources, that Webpack is how to achieve packaging? Let’s take a look today.

To understand how Webpack packaging works, we need to know two things in advance

1. What is require?

The first thing that probably comes to mind when you think of require is import, which is an ES6 syntactic standard,

— Require is a runtime call, so require can theoretically be used anywhere in the code;

– Import is called at compile time and therefore must be placed at the beginning of the file;

In CommonJS, there is a global method called require(), which is used to load modules. AMD and CMD also use the require method.

Such as:

var add = require('./a.js'); Add (1, 2)Copy the code

Require is simply a function, and the./a.js referenced is just an argument to the function.

2. What is exports?

Exports is an object and MDN export is an object.

With require and exports in mind, we can now start packing

Let’s take a look at our packaged code structure below. We can see that require and exports are packaged.

Not all browsers can implement require exports, you have to implement both require and exports to keep your code running. The packaged code is a self-executing function, with parameters that have dependencies, and the code of the file. The body of the function being executed executes the code through Eval.

The overall design drawing is as follows:

Step 1: Write our configuration file

The configuration file configures our packaged entry and the packaged export output for later generation files.

const path = require("path"); module.exports = { entry: "./src/index.js", output: { path: Path.resolve (__dirname, "./dist"),// The output file address needs to be absolute path so need path filename:"main.js"}, mode:"development"Copy the code

Step 2: Module analysis

Overall idea: It can be summarized as follows: fs file is used to read the entry file and obtain the path of the import dependent file through AST. If the dependent file still has dependencies, it will continue recursively until the dependency analysis is clear and maintained in a map.

Detail disassembly: The ImportDeclaration function of the AST helps us to quickly filter out the import syntax. It is also possible to use regular matches. After all, the file is just a string. But not elegant enough.

Step1: create index.js, a.js, b.js dependencies are as follows

Index. Js file

import { str } from "./a.js";
console.log(`${str} Webpack`)
Copy the code

A. s file

import { b} from "./b.js"
export const str = "hello"
Copy the code

B.j s file

export const b="bbb"
Copy the code

Step2: Write a Webpack

Module analysis: use @babel/ Parser of AST to convert strings read from files into AST tree, @babel/traverse to parse, filter out import with ImportDeclaration to find out file dependencies.

const content = fs.readFileSync(entryFile, "utf-8"); const ast = parser.parse(content, { sourceType: "module" }); const dirname = path.dirname(entryFile); const dependents = {}; Traverse (ast, {ImportDeclaration({node}) {// import const newPathName = "./" + path.join(dirname, node.source.value); dependents[node.source.value] = newPathName; } }) const { code } = transformFromAst(ast, null, { presets: ["@babel/preset-env"] }) return { entryFile, dependents, code }Copy the code

The results are as follows:

We use the for loop to analyze all dependencies. Note that the length of modules is changed. When there are dependencies, the new dependency.modules. Modules.length changes.

for (let i = 0; i < this.modules.length; i++) { const item = this.modules[i]; const { dependents } = item; if (dependents) { for (let j in dependents) { this.modules.push(this.parse(dependents[j])); }}}Copy the code

Step 3: Write the WebpackBootstrap function + generate the output file

Write the WebpackBootstrap function: The first thing we need to do here is the WebpackBootstrap function, and when we compile it, our source code import will be interpreted as require, so if the browser doesn’t know require, let’s declare it first, require is a method, Another thing to be aware of when writing functions is scope isolation to prevent variable contamination. Exports in our code also needs to be declared to make sure that exports exists at the time the code executes.

Generate output file: the address of the generate file is already written in the configuration file, and then write to the output folder with fs.writeFileSync.

file(code) { const filePath = path.join(this.output.path, this.output.filename) const newCode = JSON.stringify(code); Const bundle = '(function(modules){function require(module){function pathRequire(relativePath){return  require(modules[module].dependents[relativePath]) } const exports={}; (function(require,exports,code){ eval(code) })(pathRequire,exports,modules[module].code); return exports } require('${this.entry}') })(${newCode})`; // WebpackBoostrap // Generate the file. Dist fs.writeFileSync(filePath,bundle,' utF-8 ')}Copy the code

Step 4: Analyze the order of execution

We can run the package on the browser console, and if it works it should print Hello Webpack.

conclusion

Through the above analysis, we should have a basic understanding of the general process of Webpack. Using AST to parse code is just a way of this demonstration, not the real implementation of Webpack. Webpack has its own AST parsing method, and all changes are module dependent. Webpack ecology is very complete, interested children’s shoes can consider the following three questions:

  • What if a component circular reference occurs?
  • How does Webpack load a loader?
  • Judah strongly recommended vite can achieve on-demand packaging, greatly reduce the development of packaging speed, if it is webapck and how to achieve?

Recommended reading

Why is index not recommended as key in Vue

Brief analysis of Web screen recording technology scheme and implementation

Open source works

  • Political cloud front-end tabloid

Open source address www.zoo.team/openweekly/ (wechat communication group on the official website of tabloid)

  • Item selection SKU plug-in

Open source addressGithub.com/zcy-inc/sku…

, recruiting

ZooTeam, a young passionate and creative front-end team, belongs to the PRODUCT R&D department of ZooTeam, based in picturesque Hangzhou. The team now has more than 60 front-end partners, with an average age of 27, and nearly 40% of them are full-stack engineers, no problem in the youth storm group. The members consist of “old” soldiers from Alibaba and netease, as well as fresh graduates from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. In addition to daily business docking, the team also carried out technical exploration and practice in material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, promoted and implemented a series of internal technical products, and continued to explore the new boundary of front-end technology system.

If you want to change what’s been bothering you, you want to start bothering you. If you want to change, you’ve been told you need more ideas, but you don’t have a solution. If you want change, you have the power to make it happen, but you don’t need it. If you want to change what you want to accomplish, you need a team to support you, but you don’t have the position to lead people. If you want to change the pace, it will be “5 years and 3 years of experience”; If you want to change the original savvy is good, but there is always a layer of fuzzy window… If you believe in the power of believing, believing that ordinary people can achieve extraordinary things, believing that you can meet a better version of yourself. If you want to be a part of the process of growing a front end team with deep business understanding, sound technology systems, technology value creation, and impact spillover as your business takes off, I think we should talk. Any time, waiting for you to write something and send it to [email protected]