weex中頁面其實(shí)就是一個(gè)js文件,這個(gè)js文件由頁面業(yè)務(wù)代碼
和庫代碼
組成。我們可以把庫代碼抽出來放到遠(yuǎn)端,供所有頁面使用。
weex提供的JS Service
技術(shù),它允許我們?cè)陧撁婕虞d前注入一段js代碼,在頁面加載后使用。
我們需要把庫代碼統(tǒng)一放在一個(gè)js文件中,再將這個(gè)文件放到服務(wù)器上。
一般我們的項(xiàng)目有很多的工具類,這些工具類又依賴大量的npm第三方庫。要想把這些源碼都一起放進(jìn)service文件
里,需要拿到npm第三方庫的源碼,我們可以使用webpack打包這些npm的第三方庫
新建一個(gè)js文件,只引用npm的第三方庫
// npm_libs.js
const md5 = require('md5');
const qs = require('qs');
...
module.exports = {
md5,
qs
}
用webpack打包該js文件,打包后的js需要用全局變量引用里面的module.export
var BasicLib;
...
module.exports = {
md5: md5
}
...
BasicLib = module.exports
service文件的代碼是這樣的,因?yàn)楣ぞ邘炜赡苄枰玫絯eex對(duì)象和其它變量,所以在這些變量傳進(jìn)去之后再去構(gòu)造它們
var npm_libs = ...;
var weex;
var NODE_ENV;
var someutil;
var init_someutil = function () {
someutil = {
md5: npm_libs.md5('123')
}
}
var _init = function () {
init_someutil();
}
service.register('KSService', {
create: function(id, env, config) {
return {
instance: {
},
NormalService: function(_weex, _NODE_ENV) {
weex = _weex;
NODE_ENV = _NODE_ENV;
_init();
return {
someutil
}
}
}
},
refresh: function(id, env, config){
},
destroy: function(id, env) {
}
})
這樣service文件就創(chuàng)建好了,下面看如何使用
var libs = new service.NormalService(weex, 'debug')
console.log(libs.someutil.md5)
但是實(shí)際上,我們肯定有很多的工具庫,這么多工具庫代碼全部放在一個(gè)js文件里是不合適的,所以我們先按之前的方式將工具庫代碼放進(jìn)service文件中,再將它們拆分成多個(gè)js文件,以后只對(duì)這些js文件進(jìn)行維護(hù)即可
使用腳本合并這些拆分出來的js文件
import os
import sys
root = os.path.abspath('.')
files = ['a', 'b', 'c']
servieFile = root + '/dist/' + 'service.js'
saveto = open(servieFile, 'w')
content = ''
for file in files:
path = root + '/src/libs/' + file + '.js'
exist = os.path.exists(path)
if exist is False:
print('error: file not exist ' + path)
sys.exit()
with open(path) as f:
content = content + '\n' + f.read()
saveto.write(content)
print('libs saves to ' + servieFile)
現(xiàn)在我們需要在每次代碼修改后自動(dòng)執(zhí)行這個(gè)合并腳本,可以用webpack的插件實(shí)現(xiàn)
// hook這個(gè)再執(zhí)行我們上面寫的合并腳本
compiler.plugin('emit', function(compilation, callback) {
// run py script
});
這樣,合并腳本就會(huì)在每次打包的時(shí)候自動(dòng)執(zhí)行了,但是這些拆分的js也會(huì)被打進(jìn)dist目錄,我們需要這些無用的文件,這里可以用chokidar
監(jiān)控那個(gè)目錄,有改動(dòng)就進(jìn)行目錄刪除
const unuseDistFiles = './dist/src';
chokidar.watch(unuseDistFiles).on('all', (event, path) => {
deleteDir(unuseDistFiles)
});
這樣就完成了,也可以在生產(chǎn)環(huán)境下使用uglify-es
進(jìn)行js壓縮
if (env == 'production') {
console.log('uglify js ' + path + ' started')
var code = {
"file.js": fs.readFileSync(path, "utf8"),
};
var options = {
mangle: false,
toplevel: true,
output: {
beautify: false
}
};
var result = UglifyJS.minify(code, options);
if (result.error == undefined) {
fs.writeFileSync(path, result.code, 'utf8')
console.log('uglify js ' + path + ' successed')
}
}
由于頁面js會(huì)依賴這個(gè)service文件,所以一定要確保service加載完了再去加載頁面js,否則頁面會(huì)報(bào)錯(cuò)。并且這個(gè)service文件需要和頁面文件一起進(jìn)行版本管理,保證頁面和service版本一致。
在原來的庫文件中,去引用新的service即可實(shí)現(xiàn)無縫切換。