由于種種原因兑燥,我們選擇了Ueditor作為我們的富文本編輯器選型鱼炒。
Ueditor不支持模塊化,所以無法在代碼中使用import去引入欲芹。一開始我們在項目中是將Ueditor的js文件直接通過script標簽引入卿啡,在React的代碼里直接使用window.UE去使用編輯器。但是這就有一個問題耀石,我們對UE的源碼進行了改動牵囤,加入了定制化的功能。而直接引入的UE文件在瀏覽器是有緩存的滞伟,我們每次改動都要清除緩存才能生效揭鳞。
我們要解決緩存這個問題,webpack配置就必須滿足以下條件:
- 每次改動代碼后梆奈,能自動給UE的文件名加hash
- 能自動插入html模板文件并在主入口文件加載之前加載完成
第一步
為了能讓UE的文件進入打包流程野崇,我們將它作為一個新的入口文件
const entry = {
main: ['babel-polyfill', './src/main.js'],
ueditor_config: ['./src/common/UEditor/ueditor.config.js'],
ueditor_all: ['./src/common/UEditor/ueditor.all.js']
};
new HtmlWebpackPlugin({
template: `./src/app/${key}/templates/${filename}`,
filename: `../view/${targetHtml}`,
hash: true,
chunks: [ueditor_all, ueditor_config, main]
})
按上面的配置構建完成之后,會發(fā)現(xiàn)效果并不是我們想要的
<script type="text/javascript" src="/public/main.xxxx.js"></script>
<script type="text/javascript" src="/public/ueditor.config.xxxx.js"></script>
<script type="text/javascript" src="/public/ueditor.all.xxxx.js"></script>
main.js在UE的前面亩钟,這樣main中使用window.UE就會報錯乓梨。顯然,我們需要一種方式來讓這個順序符合我們的預期清酥。
第二步
HtmlWebpackPlugin的chunksSortMode屬性是用來控制插入模板html的script標簽的順序的扶镀,默認是auto,會根據(jù)webpack給每個chunk生成的id去排序焰轻,在entry中排的越前的臭觉,id就越小,那在html中就排在前面辱志。所以這里我們第一種解決方案是蝠筑,調(diào)換一下entry順序
const entry = {
ueditor_config: ['./src/common/UEditor/ueditor.config.js'],
ueditor_all: ['./src/common/UEditor/ueditor.all.js']
main: ['babel-polyfill', './src/main.js']
};
但是這個方法有缺陷,當項目中有多個模板html需要引用入口的時候,在entry里面去控制這個排序就會遇到?jīng)_突的情況,不夠靈活焰雕。
所以我們把順序的控制權下方到每個HtmlWebpackPlugin中往核,通過把chunksSortMode設置為manual,按chunks的順序去排序犯祠,例如
new HtmlWebpackPlugin({
...
chunks: [ueditor_config, ueditor_all, main]
})
這樣竿报,生成的html中srcipt就會是下面的順序
<script type="text/javascript" src="/public/ueditor.config.xxxx.js"></script>
<script type="text/javascript" src="/public/ueditor.all.xxxx.js"></script>
<script type="text/javascript" src="/public/main.xxxx.js"></script>
現(xiàn)在看上去順序是ok了俄删,但是運行的時候忆某,我們發(fā)現(xiàn)控制臺報錯
regeneratorRuntime is not defined
第三步
第二步最后出現(xiàn)的錯誤渠缕,是我們使用的ES6新API沒有被轉換導致的。由于之前我們只是在main的入口加了babel-polyfill褒繁,而main又是在UE的后面加載的亦鳞,所以導致了報錯。所以需要將babel-polyfill放到入口第一個文件
const entry = {
ueditor_config: ['babel-polyfill', './src/common/UEditor/ueditor.config.js'],
ueditor_all: ['./src/common/UEditor/ueditor.all.js']
main: ['./src/main.js']
};
繼續(xù)運行后棒坏,第二步的錯誤已經(jīng)解決了燕差。不過,新的錯誤又出現(xiàn)了
TypeError: 'caller', 'callee', and 'arguments'
properties may not be accessed on strict mode functions or the arguments objects for calls to them
第四步
bable會默認給編譯的js加上use strict;
嚴格模式下caller坝冕、callee 和arguments 是不能使用的徒探,追溯到UE的源碼中,我們發(fā)現(xiàn)里面大量使用了arguments.callee這種寫法喂窟。
直接把源碼都改了不現(xiàn)實测暗,所以只能通過配置讓bable忽略這個文件。在.babel中我們加入如下配置磨澡,
"presets": [
"react"
],
"ignore": [
"./src/common/UEditor/ueditor.all.js"
],
到此webpack就能按照我們的預期構建UE模塊了碗啄。