前端工程化_JS 工具链_学习笔记
js工具链主要用于解决语言问题,其中有
- 兼容性
- 语言缺陷
- 语言增强
html 和 css 也有他们的工具链
html haml
document.createElement
css sass/less/stylus postcss
tailwind css-in-js styled-component
js 当然还有其他问题,本文暂时不涉及
比如:工程问题、流程问题 运维
——————————————————————————————————————
我经常在使用这个插件的时候看到core-js,在没用学习 JS 工具链之前并不知道是干什么用的
下面我们会聊到,那么开始
语言问题
兼容性
1.API兼容
- 可能出现当前版本不兼容,比如 node 版本不兼容,那么就给他定义一个函数解决
- 这种做法称为:polyfill(填充材料):core-js
- 但解决不了所有问题,比如微队列,不能用 Promise、Observer API就实现不了微队列
- 比如这个flatMap,通过core-js,这样就可以运行了
下面我详细讲一讲
首先我进行切换Now using node v10.24.1 (64-bit)
const result=[1,2].flatMap((x)=>[x,x*2]);
console.log(result);
输出会报错
此时我们需要 core-js 来帮助我们
先用 npm 下载
npm i core-js
补齐代码
require('core-js/modules/es.array.flat-map')
const result=[1,2].flatMap((x)=>[x,x*2]);
console.log(result);
再运行
这样就可以正常使用了
2.语法兼容
比如浏览器不兼容 ES6
async function test() {
return await Promise.resolve(1);
}
(async ()=>{
const r=await test();
console.log(r);
})();
语法兼容就不是API了,API 填充即可
是转换
-
syntax transformer(runtime)
- ...(展开运算符)
- 解构
- async await
* yield
-
需要安装工具 regenerator
-
npm i regenerator
-
我们新建一个编译器
- 编译的含义就是转换,把一种代码转换成另一种代码,这就是编译
- 编译器就是实现这种转换的工具
const regenerator = require('regenerator'); const result = regenerator.compile('原始代码', { includeRuntime: true, }) console.log(result.code);
大致代码如上
我们再试一下编译上面的代码
-
显然,编译产生了大量代码
因为使用的是 node,也可以读文件
const regenerator = require('regenerator');
const fs = require('fs');
const path = require('path');
const sourcePath = path.resolve(__dirname, './source.js');
const source = fs.readFileSync(sourcePath, 'utf8');
const result = regenerator.compile(source, {
includeRuntime: true,
})
console.log(result.code);
source.js 文件里面就是刚刚的异步代码
我们也可以把转换后的代码放到另一个文件中
const regenerator = require('regenerator');
const fs = require('fs');
const path = require('path');
const { log } = require('console');
const sourcePath = path.resolve(__dirname, './source.js');
const source = fs.readFileSync(sourcePath, 'utf8');
const result = regenerator.compile(source, {
includeRuntime: true,
})
const targetPath = path.resolve(__dirname, './target.js');
fs.writeFileSync(targetPath, result.code, 'utf-8');
console.log('compile success!');
运行之后就会多出一个文件
这个代码还可以运行,运行结果为1
综上,我们做的事情是:
我们用 js 代码写了这么一个工具,这个工具是利用 regenerator 的功能,将某一个原始的代码文件的内容,它其中的 async 和 await 语法,对他进行转换,把转换之后的代码放到另一个文件里面
语言增强
比如:
jsx 通过转换工具可以转换
<h1>xxx<h1>
---> React.createElement('h1','xxx')
TypeScript tsc ---> JS
因为要做太多转换,那有没有集成工具呢?
那什么能给这些转换工具连成串,那就是代码集成转换工具 -> babel
使用命令
npm i -D @babel/core @babel/cli
下载了两个部分,其中 cli 调用 core(里面有函数)里面的功能
source.js 的内容是
const obj={};
obj?.foo?.bar?.baz;
可以直接写在这
就是编译源文件并将输出保存到目标文件,-o
用于指定输出文件到babel/target.js
"compile": "babel babel/source.js -o babel/target.js"
运行:
npm run compile
这。。。完全没变化
其实这里做的是转换成抽象语法树
可以去这个网站看
然后转回来又变成代码,可以加入插件从而影响转换结果
现在下载可以处理可选链的插件
npm i -D @babel/plugin-proposal-optional-chaining
安装完成还不够,还需要告诉 babel 要应用这个插件
在文件夹下创建,babel.config.js
module.exports = {
plugins: ['@babel/plugin-proposal-optional-chaining']
}
然后再进行编译
这下有变化了
那要这样一个一个插入和前面一个一个加区别不大
babel 呢,还有预设,也就是一堆插件,也就有了集成效果
@babel/preset-env
npm i -D @babel/preset-env
babel.config.js
,配置中放在数组里面
module.exports = {
presets: [['@babel/preset-env', {
targets: {
edge: '17',
firefox: '60',
chrome: '67',
safari: '11.1',
},
useBuiltIns: 'usage',
corejs: '3.39.0',
}]]
};
再 npm run compile
可见操作了,效果如上图所示
END
本文主要讲到了 JS 的工具链,其中主要涉及语言问题,那么 js 语言有兼容性和语言缺陷的问题,从兼容性角度出发,有 API 兼容和语法兼容,这分别有一系列工具来解决,API 可以用 core-js 解决,语法兼容则可以通过插件解决,与此同时出现了一个集大成者,babel,它是语言的增强,代码集成转换工具