掌握JS模組化開發,編寫高可用程式碼
阿新 • • 發佈:2020-11-28
開發一個模組管理引擎:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <script>//AMD require.js // CMD sea.js //COMMONJS Node.js //UMD let module = (function () { const moduleList = {}; function define(name, modules, action) { modules.map((m, i) => { modules[i] = moduleList[m]; //獲取到依賴的方法}); moduleList[name] = action.apply(null, modules); // console.log(moduleList); } return { define }; })(); module.define('arr', [], function () { console.log('define'); return { first(arr) {return arr[0]; }, max(arr, key) { return arr.sort((a, b) => b[key] - a[key])[0]; } } }); module.define('lesson', ['arr'], function (arr) { let data = [ { name: 'html', price: 199 }, { name: 'css', price: 265 }, ]; // console.log(arr); console.log(arr.max(data, 'price')); }); module.define('a', [], function () { return { name: 'cyy', age: 18 } }); module.define('b', ['a'], function (a) { a.name = 'cyy2'; }); module.define('c', ['a'], function (a) { console.log(a); }); </script> </body> </html>
模組的基本使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <script type="module"> //引入時當前路徑的./不可省略 import { name, age, show } from './script.js'; console.log(name, age); show(); </script> </body> </html>
script.js
let name = 'cyy'; let age = 18; function show() { console.log('show'); } export { name, age, show };
模組延遲解析與嚴格模式:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 模組會在最後執行,此時元素已經渲染完畢 --> <!-- 使用type="module"時,預設是嚴格模式 --> <script type="module"> let div0 = document.querySelector('div'); console.log(div0); </script> <!-- 普通js必須在元素渲染之後使用 --> <script> let div = document.querySelector('div'); console.log(div); </script> <div>cyy</div> <script> let div2 = document.querySelector('div'); console.log(div2); </script> </body> </html>
作用域在模組中的體現:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 普通指令碼在全域性頂級作用域裡 --> <script> let url = 'www.baicu.com'; console.log(url); </script> <!-- module在自己的塊級作用域裡 可以訪問頂級作用域的內容 但是頂級作用域裡的內容不能訪問到module裡面的 --> <!-- 想要使用module裡的內容,必須要通過匯入和匯出 --> <script type="module"> // console.log(url); let cyy = 'cyy'; export { cyy }; </script> <script> console.log(url); </script> </body> </html>
預解析的必要性:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 多次重複匯入時會報錯 --> <script type="module"> import { name, age } from './script.js'; import { name, age } from './script.js'; import { name, age } from './script.js'; console.log(name); </script> </body> </html>
模組的具名匯出與匯入:
// export let name = 'cyy';
// export function show() { console.log('show') }
// export class User {
// static func() {
// console.log('User-static-func');
// }
// }
// 具名匯出
// 批量匯出
let name = 'cyy';
function show() { console.log('show') }
class User {
static func() {
console.log('User-static-func');
}
}
export { name, show, User };
批量匯入與建議:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 具名匯入 --> <script type="module"> // 批量匯入並設定別名 import * as api from './script.js'; console.log(api.name); api.show(); api.User.func(); </script> </body> </html>
別名使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 具名匯入 --> <script type="module"> // 給匯入的模組設定別名 import { name as n, s } from './script.js'; let name = 'cyy2'; console.log(n); console.log(name); s(); </script> </body> </html>
script.js
// 批量匯出 let name = 'cyy'; function show() { console.log('show') } class User { static func() { console.log('User-static-func'); } } // 匯出也可以設定別名 export { name, show as s, User };
default預設匯出:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 具名匯入 --> <script type="module"> // 預設匯出的模組,匯入時隨便起什麼名字都可以 // import myModule from './script.js'; // myModule.func(); import myModule from './script.js'; myModule.func(); </script> </body> </html>
script.js
// 當模組只有一個功能時,可以設定預設匯出 // 預設匯出1 // export default class User { // static func() { // console.log('User-static-func'); // } // } // 預設匯出2 class User { static func() { console.log('User-static-func'); } } export { User as default };
混合匯入匯出的使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 具名匯入 --> <script type="module"> // 具名匯出的需要花括號,預設匯出的不需要花括號 // import myModule, { show } from './script.js'; // myModule.func(); // show(); import * as api from './script.js'; console.log(api); </script> </body> </html>
script.js
// export default class User { // static func() { // console.log('User-static-func'); // } // } // export function show() { // console.log('show'); // } class User { static func() { console.log('User-static-func'); } } function show() { console.log('show'); } export { User as default, show };
預設匯出模組的使用規範:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <!-- 具名匯入 --> <script type="module"> // 預設匯出的模組建議跟檔名同名,這樣比較規範 import script from './script.js'; script.func(); </script> </body> </html>
模組的合併匯出:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <script type="module"> import * as api from './index.js'; console.log(api); </script> </body> </html>
index.js
import * as script from './script.js'; import * as script2 from './script2.js'; export { script, script2 };
script.js
export default class User { static func() { console.log('User-static-func'); } }
script2.js
let name = 'cyy'; function show() { console.log('show'); } export { name, show };
按需動態載入模組:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>demo</title> <style> </style> </head> <body> <button>click me</button> <script type="module"> // document.querySelector('button').addEventListener('click', function () { // //點選按鈕之後按需載入模組 // import('./script.js').then(module => { // console.log(module); // }) // }); document.querySelector('button').addEventListener('click', function () { //點選按鈕之後按需載入模組 import('./script2.js').then(({ name, show }) => { console.log(name); show(); }) }); </script> </body> </html>
script2.js
let name = 'cyy'; function show() { console.log('show'); } export { name, show };
WEBPACK構建專案的軟體安裝:
webpack打包工具,安裝之前先安裝node.js
使用一下命令生成配置檔案package.json
npm init -y
安裝webpack工具包,如果安裝慢可以使用淘寶cnpm(opens new window)命令
cnpm i webpack webpack-cli --save-dev
修改package.json
新增打包命令,實時檢視更新後的效果
... "main": "index.js", "scripts": { "dev": "webpack --mode development --watch" }, ...
目錄結構
index.html --dist #壓縮打包後的檔案 --src ----index.js #入口 ----style.js //模組
index.html內容如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> </head> <body> <script src="dist/main.js"></script> </body> </html>
index.js內容如下
import style from "./style"; new style().init();
style.js
export default class Style { constructor() { } init() { document.body.style.backgroundColor = 'pink'; } }
執行打包
執行以下命令將生成打包檔案到dist
目錄,因為在命令中添加了--watch
引數,所以原始檔編輯後自動生成打包檔案。
npm run dev
可以看到html頁面背景已經變成了粉色~