市场调研
2023.01.15 babel和webpack仍未解决.
babel: babel.docschina.org/repl/#?brow… 保留了top-level-await, 实属一脸蒙蔽
webpack: github.com/webpack/web… 额... rollup: github.com/rollup/roll… 貌似有人尝试了一波,然后又放弃了
mjs能不能转cjs
不用top-level-await能直接转, 跟esm转cjs一样, 用了就不能直接转, 必须用promise包一层.
top-level-await是啥:
res.mjs
const sleep = (time) => new Promise(resolve => {
setTimeout(() => resolve(1), time);
});
(async () => {
for (let i = 0; i < 1000 * 1000; i++) {
await sleep(500);
console.log('from res.mjs', i);
}
})();
export const foo = 1;
const res = await sleep(2000); // mjs最外层能使用await,最外层的就是top-level-await
export default res;
index.mjs
console.log('run');
import res, { foo } from './res.mjs';
const sleep = (time) => new Promise(resolve => {
setTimeout(() => resolve(1), time);
});
(async () => {
for (let i = 0; i < 1000 * 1000; i++) {
await sleep(500);
console.log('from index.mjs', i);
}
})();
console.log('res', res);
执行结果:
所以,用了top-level-await后,import res from './res.mjs'
得等到res.mjs执行完之后, 再执行后面的代码。
如何转
res.mjs -> res.cjs
// 1. 封装promise
const mjsPromise_res = async () => {
// 2. 创建module
const module = {};
const sleep = (time) => new Promise(resolve => {
setTimeout(() => resolve(1), time);
});
(async () => {
for (let i = 0; i < 1000 * 1000; i++) {
await sleep(500);
console.log('from res.mjs', i);
}
})();
// 3. 导出语法转换
module.foo = 1;
const res = await sleep(2000); // mjs最外层能使用await,最外层的就是top-level-await
// 3. 导出语法转换
module.default = res;
// 4. 导出
return module;
};
export default mjsPromise_res;
index.mjs -> index.cjs
// 1. import转为promise,并提升到文件最顶部
const mjsPromise_res = require('./res.mjs');
// 2. 执行promise, 并将文件内的内容原封不动放入then中, then的参数也得变
mjsPromise_res().then(async ({ default: res, foo }) => {
console.log('run');
const sleep = (time) => new Promise(resolve => {
setTimeout(() => resolve(1), time);
});
(async () => {
for (let i = 0; i < 1000 * 1000; i++) {
await sleep(500);
console.log('from index.mjs', i);
}
})();
console.log('res', res);
});
然后开始实现
等我(个屁, 又懒又菜),或者谁来帮忙...
mjs转cjs的意义何在
现在好多npm包都用mjs重写了, 如果作者正常写不用top-level-await
的话还好, cjs写出来的包还是可以通过esm转cjs的方式去引用的, 就是得额外配置而已.
但是如果用了top-level-await
, 那mjs和cjs就不能互相引用了, 因为至今好像都没人实现mjs转cjs的工具, 所以这个意义真的很大啊.