[英]Support for ES6 imports in ES5 module
對於我的一年級學生,我提供了一個使用 Revealing Module Pattern 編寫的基於 ES5 的簡單庫。 這是“主”模塊/命名空間的一個片段,它將容納其他擴展:
window.Library = (function ($) {
if (!$) {
alert("The Library is dependent on jQuery, which is not loaded!");
}
return {};
})(window.jQuery);
這適用於幾乎 99.9% 的 Web 開發新手,並且沒有將 ES6 等花哨的東西與 Webpack 或 Babel 結合使用。
0.1% 現在要求我提供基於 ES6 的版本,可以正確導入。 我很樂意提供這個,但我有點堅持如何最好地解決這個問題。
我顯然想保持 ES5 的方式,所以我的學生可以使用腳本標簽和類型Library.SomeExtension.aFunction();
來包含文件Library.SomeExtension.aFunction();
他們喜歡的地方。 最重要的是,一些擴展依賴於 jQuery,它以與上面的代碼片段類似的方式注入。
我現在正在尋找一些可維護的方法來獲得兩全其美的方法,使用一個代碼庫,將 jQuery 作為依賴項。 我想給 99.9% 一個window.Library
,而我想給 0.1% 一種使用import Library from 'library'
。
我可以用一個 JS 文件來完成這兩個任務嗎? 或者我需要一個特殊的 ES6 版本(不是問題)? 最重要的是:我將如何以可以支持兩種情況的方式重新調整我的代碼(都類似於上面的代碼段)?
任何和所有指針將不勝感激!
編輯:作為旁注,我已經有了一個gulpfile.js
,它通過Babel
、 minifiers
和其他東西運行這個庫。 所以必須擴展它來解決上述問題不是問題!
經過幾個晚上的移動代碼並安裝了如此多的 gulp 軟件包,我什至不記得我嘗試過的所有軟件包,我最終確定了一些我不太滿意的東西。
首先,回答我自己的問題,@Bergi 在評論中也支持這個問題:
簡短回答:不,您不能以任何方式(現在)將 ES6 語法與 ES5(模塊)混合在一個文件中,因為瀏覽器會在使用
export
出錯。長答案:從技術上講,您可以將腳本元素類型設置為“模塊”,這將使瀏覽器接受
export
關鍵字。 但是,您的代碼只會運行兩次(一次在加載時,一次在導入后)。 如果你能忍受這一點,那么“否”就變成了“是”,有點。
那么我最終做了什么? 讓我先說一下,我真的很想在輸出 ES5 文件中保留我(現在)擁有的 IIFE 模塊設置。 我將我的代碼庫更新為純 ES6,並嘗試了各種插件組合(包括 @David Bradshaw 提到的 Rollup.js)。 但是我根本無法讓它們工作,或者它們會以瀏覽器無法再加載模塊或放棄源映射支持的方式完全破壞輸出。 隨着學生們正在進行的項目即將結束,我已經為 0.1% 的學生浪費了足夠的業余時間。 因此,明年有一個“更好”的解決方案,祝你好運。
我基於 jQuery 的 UMD 模式(如@Sly_cardinal 所述)並將該代碼放入Library.umd.js
。 對於 ES6 部分,我創建了一個Library.es6.js
其中只有一個export default Library
。
在這兩個文件中,我都放置了一個多行注釋/*[Library.js]*/
,我想在其中注入連接的未縮小的 Library.js。
我修改了我現有的 Gulp 任務,只使用concat
和Babel
構建Library.js
並將其存儲在一個臨時位置。 我選擇在這個過程中犧牲源映射支持,因為連接的代碼在輸出中是完全可讀的。 從技術上講,源映射支持“有效”,但它仍然會過多地拋棄調試器。
我添加了一個額外的 Gulp 任務來讀取 temp Library.js
的內容,然后對於步驟 1 中的每個文件,我會找到並用內容替換多行注釋。 保存生成的文件,然后將它們通過最終的concat
(例如與 jQuery 捆綁)、 terser
和 sourcemap 生成。
最終結果是兩個文件:
雖然我對結果很滿意,但我不喜歡 Gulp 任務鏈和流程前半部分失去 sourcemap 支持。 如前所述,我嘗試了許多 gulp 插件來實現相同的效果(例如gulp-inject
),但它們要么無法正常工作,要么對源映射做了奇怪的事情(即使他們聲稱支持它)。
在接下來的努力中,我可能會研究與 Gulp 不同的東西,或者制作我自己的插件來完成上述工作,但正確:P
您可以使用Rollup.js將您的代碼捆綁為 ES5 庫以及隨附的 ES6 模塊。
Rollup內置了對 Gulp 的支持,所以像這樣的東西將是一個合理的起點(基於 Rollup 的 Gulp 示例):
const gulp = require('gulp');
const rollup = require('rollup');
const rollupTypescript = require('rollup-plugin-typescript');
gulp.task('bundle', () => {
return rollup.rollup({
input: './src/main.ts',
plugins: [
rollupTypescript()
]
}).then(bundle => {
return Promise.all([
// Build for ES5
bundle.write({
file: './dist/library.js',
format: 'umd',
name: 'Library',
sourcemap: true
}),
// Build for ES6 modules
bundle.write({
file: './dist/library.esm.js',
format: 'esm',
sourcemap: true
})
]);
});
});
您可以查看有關可用的不同輸出格式的更多信息: https : //rollupjs.org/guide/en/#outputformat
如果您的庫源代碼是使用 ES 模塊編寫的,然后捆綁/轉換為 ES5 捆綁包,則通常是最簡單的。
它們是Universal JS Loader Patten ,它允許您以多種不同的方式導出代碼。
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.YourModule = factory();
}
}(this, function () {
return {};
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.