bigbossx / blog Goto Github PK
View Code? Open in Web Editor NEWShare something useful or interesting 👀
Share something useful or interesting 👀
哎~朋友们好啊,我是练习时长三年半的前端小老板,昨天有个朋友问我,b导师,发生甚么事了,我说怎么回事,给我发了几张截图,我一看,哦,原来是佐天,有两个年轻人,20多岁,一个刚毕业,一个工作一年多了,塔门说,哎~有一个说是,我在天天在src目录下写代码,开发,一点进步都没有,b导师,你能不能教教我webpack相关的知识,哎~帮助学习一下。我说可以,我说你在src目录下练死劲不管用,他不服气。哎~我说小朋友,看我教你怎么跑项目,他说你这也没用。我说我这个有用,这是项目配置,传统前端是讲工程化的,四两拨千金, 国内国外很多大公司前端项目走的都是这样的流程,他说要我试试,我说可以,哎~我说一完他啪的一下就坐过来了,很快啊!然后我上来就是一个npm install
咳!一个npm start
全部成功了,成功了啊,成功了以后自然是传统前端,8080端口,输在浏览器上没打开,我笑一下准备 ctrol c,因为这时间,按照传统前端的流程,已经打包完了,他也承认,都没报错,他承认是我跑成功了啊,我ctrol c的时间,不跑了,他突然说一句,配置了构建完之后自动打开p站,我大意了啊,没有删,哎~很快就自动打开浏览器,当时很多同事看到了,我说婷婷,但没关系啊,两分多钟之后我关闭了,我说小伙子你不讲伍德,他说b导师对不起对不起,我不懂配置,我是乱加的,他说他是乱加的他可不是乱加的啊,webpack函数 一个配置对象,一个成功回调,训练有素,后来他说他看过几章webpack文档,看来是有备而来,我劝!这位年轻人耗子尾汁,构建,要讲环境,以安全可靠为贵,不要再犯这样的聪明,小聪明啊,谢谢朋友们。
我们通常将源码
-> 产物
的过程称之为打包
或者叫构建
,在此过程中,我们将获取到源代码内容,重新组装,转换,压缩,混淆,修改...等等一系列的操作,以达到一些非常简单原始的目的:
通常来说越复杂的东西,越应该精细化和自动化,工具化等,webpack也是在web应用逐渐复杂的背景下诞生的。
我习惯了解一个东西先去了解时代背景,作者一开始的**,这样我能更快的知道他为什么做,当时能怎么做,后来怎么做了更多。思路 > 代码实现,当然代码实现仍然是我们非常应该学习然后积累的点。
webpack 开始于2012年 sokra 的一个被拒绝的功能请求 medikoo/modules-webmake#7 基于modules-webmake sokra提出,增加类似Code Splitting的功能。即我们的构建可以有如下的功能:
让我们回头来看看,这些是什么,然后在解决什么问题,首先是
我们知道js在esm之前并没有模块规范标准,但是随着web应用的不断复杂化,代码的模块化成为不可或缺的一点,你可以在这些文章详细了解
不再赘述,但我们总结出几个关键点:(在js esm规范之前)
1、AMD CMD 等实现,都有一个函数包裹,即回调函数内,才是模块代码,再详细一点呢?
相反nodejs则没有那层函数包裹,module
exports
require
__dirname
__filename
都是当前文件的,文件之间变量是隔离的,node是怎么做到的?答案是
我们从上面的知识已经知道了,不管是AMD CMD还是commonjs,他都是函数包裹的函数作用域
那我们通过构建这一层,使得在开发时去掉这层包裹,由构建工具自动补上,不就跟nodejs一模一样了吗!
所以最终,我们知道了如果我们产物长这个样子,那我们的commonjs风的代码,是可以在浏览器完完整整的运行起来的。即实现了allows you to organize JavaScript code for the browser the same way as you do for Node.js
(function(modules /* 所有可用的模块 */) {
var installModules = {};
function magicRequire(id) {
if (installModules[id]) {
return installModules[id].exports;
}
var module = (installModules[id] = {
exports: {},
id: id,
});
modules[id](module, module.exports, magicRequire);
// modules[id].call(module,module, module.exports, magicRequire); // commonjs 规范,this指向当前模块
return module.exports;
}
magicRequire("entry");
})({
"entry": function(module, exports, require) {
var addModule = require("./add");
const temp = addModule.add(1, 1);
var { square } = require("./square");
console.log(square(temp,temp))
},
"./add": function(module, exports, require) {
module.exports = {
add: function(x, y) {
return x + y;
}
};
},
"./square": function(module, exports, require) {
var { multiply } = require("./multiply");
module.exports = {
square: function(num) {
return multiply(num, num);
}
};
},
"./multiply": function(module, exports, require) {
module.exports = {
multiply: function(x, y) {
return x * y;
}
};
}
})
这也即是webpack所说的runtime 运行时 + modules 模块,由runtime组织起来module之间的逻辑运行
从上面的产物可以知道,这个产物是一个js文件,它不止一个module,所以我们不能再叫module了,给它取了个时兴的名字:chunk
上面这个chunk = runtime + module 。我们可以再进一步把它拆分, runtime 独立出来,叫runtime chunk,modules 部分就叫module chunk吧。
modules就是当前我们所有可用的模块集合,但是,我们的项目可能非常庞大,所以如果将所有的模块组合在同一个js 里面,将会非常大,所以我们需要有组织的将modules 的部分拆分出去。拆分出去的这一部分多个模块组成的js产物文件,我们称为异步chunk
然后我们提供一个类似jsonp的方案,sciprt标签加载异步chunk,通过jsonp回调将额外的module merge 到modules 中,即
(function(modules /* 所有可用的模块 */) {
// ...
window.webpackJsonp=function(chunkid,moreModules){
for(const key of moreModules){
modules[key]=moreModules[key]
}
}
})({
// ...
})
// a.chunk.sd2321sd.js
webpackJsonp("sd2321sd",{
'more1':function(){...},
'more2':function(){...},
'more3':function(){...},
})
好了1、2点已经实现了,让我们再加上image和css的加载,其实也非常简单。
对于图片,我们require它的时候,我们希望返回的是一个合法的src 源就可以,例如base64,或者是一个url路径
对于css ,我们require它的时候,我们需要做的就是创建一个style,并且append 到 document head 就可以。
{
image: function (module, exports, require) {
module.exports = "/images/header.ada3q43.jpg";
},
css: function (module, exports, require) {
var style = "h1[data-v-1111]{color:yellow;}"; // scoped
const styleElem = document.createElement("style");
styleElem.innerHTML = style;
document.head.appendChild(styleElem);
},
}
所以,我们现在可以知道了,webpack 的构建核心,是生成组织者:runtime 和各个module的组合:modules
我们来试试,手把手的构建一次,一个mini react hello world
const react = require("react");
const reactDom = require("react-dom");
const reactIcon= require("react-icon")
var image= react.createElement("img", { src: reactIcon }, null)
var component = react.createElement("h1",{},"Hello ", image ,". Welcome!");
reactDom.render(component, document.getElementById("app"));
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.