javascript中的子產品化
文章目錄
- javascript中的子產品化
- ES6子產品化
- 導出
- 轉譯工具
- babel
- 預設
- 離線轉譯安裝配置
- 1.初始化npm
- 2.設定鏡像
- 3.安裝
- 4.修改package.json
- 5.準備目錄
- 6.配置babel和安裝依賴
- 7.準備js檔案
- 8.轉義js檔案
- 9.可能出現的錯誤
- 導入導出
- 預設導入導出
ES6之前,js沒有出現子產品化系統。
- JS主要在前端的浏覽器中使用,js檔案下載下傳緩存到用戶端,在浏覽器中執行。比如簡單的表單本地驗證,漂浮一個廣告。伺服器端使用ASP、JSP等動态網頁技術,将動态生成資料嵌入一個HTML模闆,裡面夾雜着JS後使用
标 簽,傳回浏覽器端。這時候的JS隻是一些簡單函數和語句的組合。<script>
- 2005年之後,随着Google大量使用了AJAX技術之後,可以異步請求伺服器端資料,帶來了前端互動的巨大變化。 前端功能需求越來越多,代碼也越來也多。随着js檔案的增多,災難性的後果産生了。由于習慣了随便寫,js腳本 中各種全局變量污染,函數名沖突,無法表達腳本之間的依賴關系,因為都是用腳本檔案先後加載來實作的。亟待 子產品化的出現。
- 2008年V8引擎釋出,2009年誕生了Nodejs,支援服務端JS程式設計,但沒有子產品化是不可以的。
- 之後産生了commonjs規範。commonjs規範,使用全局require函數導入子產品,使用exports導出變量。為了将這種子產品化規範向前端開發遷移,又演化出其它的規範。例如AMD。
- AMD(Asynchronous Module Definition)異步子產品定義,使用異步方式加載子產品,子產品的加載不影響它後面語 句的執行。所有依賴這個子產品的語句,都需要定義在一個回調函數,回調函數中使用子產品的變量和函數,等子產品加 載完成之後,這個回調函數才會執行,就可以安全的使用子產品的資源了。其實作就是AMD/RequireJs。AMD雖然是 異步,但是會預先加載和執行。
- CMD(Common Module Definition),使用seajs,作者是淘寶前端玉伯,相容并包解決了RequireJs的問題。 CMD推崇as lazy as possible,盡可能的懶加載。
- 由于社群的子產品化呼聲很高,ES6開始提供支援子產品的文法,但是浏覽器目前支援還不夠。
ES6子產品化
- import語句,導入另一個子產品導出的綁定。
- export語句,從子產品中導出函數、對象、值的,供其他子產品import導入用。
導出
- 建立一個子產品目錄src,然後在這個目錄下建立一個moda.js,内容如下:
//預設導出
export default class A{
constructor(x){
this.x = x;
}
show(){
console.log(this.x)
}
}
//導出函數
export function foo(){
console.log('foo function');
}
//導出常量
export const CONSTA = 'aaa';
- 在src目錄中建立text.js導入moda.js中的内容,并使用,如下:
import {A,foo} from "./moda"
import * as mod_a from "./moda"
VS Code可以很好的文法支援了,但是運作環境,包括V8引擎,都不能很好的支援子產品化文法。
轉譯工具
轉譯就是從一種語言代碼轉換到另一個語言代碼,當然也可以從高版本轉譯到低版本的支援語句。
由于JS存在不同版本,不同浏覽器相容的問題。可以使用transpiler轉譯工具解決。
babel
- 開發中可以使用較新的ES6文法,通過轉譯器轉換為指定的某些版本代碼。
- 官網https://babeljs.io/
- 參考文檔https://babeljs.io/docs/en/6.26.3/index.html注意目前版本7.x已經有了較大的變化,請參看6.x文檔
- 在
。中可測試代碼Try it out

預設
- 有如下一些預設presets,我們先看看有哪些,一會兒再進行預設的安裝和配置
- presets:
-
目前環境支援的代碼,新targetbabel-preset-env
- ES2015轉碼規則
-
npm install --save-dev babel-preset-es2015
- react轉碼規則
-
npm install --save-dev babel-preset-react
- ES7不同階段文法提案的轉碼規則(共4個階段),選裝一個
-
npm install --save-dev babel-preset-stage-0
-
npm install --save-dev babel-preset-stage-1
-
npm install --save-dev babel-preset-stage-2
-
npm install --save-dev babel-preset-stage-3
離線轉譯安裝配置
1.初始化npm
- 打開cmd指令視窗,進入項目根目錄。輸入
初始化項目根目錄npm init
PS D:\MyPythonUse\WebJS> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (webjs) test
version: (1.0.0)
description: babel
entry point: (test.js)
test command:
git repository:
keywords:
author: xdd
license: (ISC)
About to write to D:\MyPythonUse\WebJS\package.json:
{
"name": "test",
"version": "1.0.0",
"description": "babel",
"main": "test.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "xdd",
"license": "ISC"
}
Is this OK? (yes) yes
PS D:\MyPythonUse\WebJS>
- 在項目根目錄下會生成package.json檔案,内容就是上面花括号的内容。
2.設定鏡像
-
檔案。修改npm安裝軟體時預設連接配接倉庫為淘寶的npm倉庫。.npmrc
- 可以放到npm的目錄下npmrc檔案中
- 可以放到使用者家目錄中
- 可以放到項目根目錄中
- 本次放到項目根目錄黃總,内容如下:
- 在項目更目錄中建立一個檔案名為
的檔案。寫入.npmrc
registry=https://registry.npm.taobao.org
-
$ echo "registry=https://registry.npm.taobao.org" > .npmrc
3.安裝
- 項目根目錄下執行
npm install babel-core babel-cli --save-dev
- –save–dev說明:當你為你的子產品安裝一個依賴子產品時,正常情況下你得先安裝他們(在子產品根目錄下npm install module-name),然 後連同版本号手動将他們添加到子產品配置檔案package.json中的依賴裡(dependencies)。開發用。–save和–save-dev可以省掉你手動修改package.json檔案的步驟。
-
自動把子產品和版本号添加到dependencies部分spm install module-name --save
-
自動把子產品和版本号添加到devdependencies部分spm install module-name --save-dev
- 安裝完後,在項目根目錄下出現
目錄 ,裡面有babel相關子產品及依賴的子產品。node_modules
4.修改package.json
- 修改package.json檔案中scripts的部分,添加
。"build": "babel src -d lib"
-
從src目錄中轉譯後的檔案輸出到lib目錄"build": "babel src -d lib"
- 修改
為"license": "ISC"
"license": "MIT"
5.準備目錄
- 項目根目錄下建立src和lib目錄。
- src是源碼檔案目錄。
- lib是目标目錄。
6.配置babel和安裝依賴
- 在目錄根目錄下建立
檔案,Json格式。.babelrc
{
"presets":["env"]
}
-
可以根據目前環境自動選擇。env
- 安裝依賴
npm install babel-preset-env --save-dev
7.準備js檔案
- 在src中的mod.js
// 預設導出
export default class A{
constructor(x){
this.x = x;
}
show(){
console.log(this.x);
}
}
export function foo(){
console.log('foo function');
}
- 在src目錄下的index.js
import A,{foo} from './mod'
var a = new A(100);
a.show();
foo();
- index.js這段代碼在vs Code的環境下執行出錯。估計很難有能夠正常運作的環境。是以,要轉義為ES5的代碼。
8.轉義js檔案
- 在項目根目錄下執行指令
npm run build
$ npm run build
> [email protected] build D:\MyPythonUse\WebJS
> babel src -d lib
src\index.js -> lib\index.js
src\mod.js ->
- 可以看到兩個檔案被轉義,運作轉義檔案
node lib/index.js
$ node lib/index.js
100
foo function
- 使用babel等轉譯器轉譯JS非常流行。開發者可以在高版本中使用新的文法特性,提高開發效率,把相容性問題交給轉譯器處理。
9.可能出現的錯誤
-
檔案錯誤。重新删除.babelrc
檔案後再重建立立一個該檔案。.babelrc
- 錯誤資訊
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ npm run build
> [email protected] build D:\MyPythonUse\WebJS
> babel src -d lib
SyntaxError: D:\MyPythonUse\WebJS\.babelrc: Error while parsing JSON - Unexpected '�' at line 1 column 2 of the JSON5 data. Still to read: "��{\u0000\r\u0000\n\u0000\t\u0000\"\u0000p\u0000r\u0000e\u0000s\u0000"
at error (D:\MyPythonUse\WebJS\node_modules\json5\lib\json5.js:56:25)
at word (D:\MyPythonUse\WebJS\node_modules\json5\lib\json5.js:393:13)
at value (D:\MyPythonUse\WebJS\node_modules\json5\lib\json5.js:493:56)
at Object.parse (D:\MyPythonUse\WebJS\node_modules\json5\lib\json5.js:508:18)
at ConfigChainBuilder.addConfig (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\options\build-config-chain.js:150:65)
at ConfigChainBuilder.findConfigs (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\options\build-config-chain.js:96:16)
at buildConfigChain (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\options\build-config-chain.js:61:13)
at OptionManager.init (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\options\option-manager.js:354:58)
at File.initOptions (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\index.js:212:65)
at new File (D:\MyPythonUse\WebJS\node_modules\babel-core\lib\transformation\file\index.js:135:24)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `babel src -d lib`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR!
- 解決辦法
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ rm .babelrc
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ echo "{\"presets\": [\"env\"]}" >.babelrc
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ cat .babelrc
{"presets": ["env"]}
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ npm run build
> [email protected] build D:\MyPythonUse\WebJS
> babel src -d lib
src\index.js -> lib\index.js
src\mod.js ->
導入導出
- 說明:導出代碼都在src/mod.js中,導入代碼都寫在src/index.js中。
預設導入導出
- 隻允許一個預設導出,預設導出可以是變量、函數、類,但不能使用let、var、const關鍵字作為預設導出。
- 預設導入,不需要在import後使用花括号。
- 預設導入的時候,可以自己重新命名,可以不需要和預設導出時的名稱一緻,但最好一緻。
- 可以使用
文法來導入所有導出。import * as 新名稱 from '子產品'
- src/mod.js中
//預設導出 匿名函數
export default function() {
console.log('我是預設導出')
}
- src/index.js中
//預設導入
import defaultFunc from './mod'
defaultFunc();
- 控制台執行指令:
$ npm run build
> [email protected] build D:\MyPythonUse\WebJS
> babel src -d lib
src\index.js -> lib\index.js
src\mod.js ->
- 第二種示例
// mod子產品中
// 預設導出 命名函數
export default function xyz(){
console.log('default export function')
}
// index子產品中
//預設導入
import defaultFunc from './mod'
defaultFunc();
- 命名導入和導出
- src/mod.js中
/**
* 導出舉例
*/
//預設導出 類
export default class {
constructor(x){
this.x = x;
}
show(){
console.log(this.x);
}
}
// 命名導出 函數
export function foo(){
console.log('我是函數foo');
}
// 定義函數
function bar(){
console.log("我是函數bar()");
}
// 變量常量定義
let x = 100;
var y = 200;
const z = 300;
//導出
export {bar,x,y,z}
- src/index.js中
/**
* 導入舉例
* as 設定别名
*/
import defaultCls,{foo,bar,x,y,z as CONST_C} from './mod';
foo();
bar();
console.log(x); //x隻讀,不可修改,x++會出現異常
console.log(y); //y隻讀
console.log(CONST_C);
let fun =new defaultCls(1000);
fun.show();
- cmd指令行中執行
$ npm run build
> [email protected] build D:\MyPythonUse\WebJS
> babel src -d lib
src\index.js -> lib\index.js
src\mod.js -> lib\mod.js
gdy@gdy MINGW64 /d/MyPythonUse/WebJS
$ node ./lib/index.js
我是函數foo
我是函數bar()
- 在index.js檔案中也可以使用下面形式,導入所有導出,但是會定義一個新的名詞空間。使用名詞空間可以避免沖突。
import * as newmod from './mod';
newmod.foo();
newmod.bar();
new newmod.default(2000).show();