呈上個文章,如果我們想有類似 SPA 那種 routes 的功能,讓重複資源如 jQuery
統一一包該怎麼實做。
目錄結構
| | a.html |
| | b.html |
| | tsconfig.json |
| | webpack.config.js |
| +---app |
| | |
| \---src |
| | main.ts |
| | routes.ts |
| \---class |
| a.ts |
| b.ts |
| main.interface.ts |
我把 index.ts
改成了 main.ts
,增加了,程式碼內容如下:
a.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Typescript + Webpack</title> |
| <script src="app/main.js"></script> |
| </head> |
| <body id="a"> |
| <div id="content"></div> |
| </body> |
| </html> |
b.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Typescript + Webpack</title> |
| <script src="app/main.js"></script> |
| </head> |
| <body id="b"> |
| <div id="content"></div> |
| </body> |
| </html> |
main.ts
| import $ from 'jquery'; |
| import { routes } from './routes'; |
| |
| $(function () { |
| const classLoader = async (routeName: string): Promise<any> => { |
| const imported = await import('./class/' + routeName); |
| const className = routeName.toUpperCase(); |
| |
| return new imported[className](); |
| } |
| |
| routes.forEach(route => { |
| if ($(`body#${route}`).is('*')) { |
| classLoader(route).then(target => target.init()); |
| |
| return false; |
| } |
| }); |
| }); |
routes.ts
| export const routes: string[] = [ |
| 'a', |
| 'b' |
| ] |
webpack.config.js
| const path = require('path'); |
| |
| module.exports = { |
| mode: 'development', |
| entry: { |
| main: {import: './src/main.ts'} |
| }, |
| module: { |
| rules: [ |
| { |
| test: /\.tsx?$/, |
| use: 'ts-loader', |
| exclude: /node_modules/, |
| }, |
| ], |
| }, |
| resolve: { |
| extensions: ['.tsx', '.ts', '.js'], |
| }, |
| output: { |
| path: path.resolve(__dirname, 'app'), |
| }, |
| }; |
main.interface.ts
| export interface mainInterface { |
| init(): void |
| } |
a.ts
| import { mainInterface } from './main.interface'; |
| import $ from 'jquery'; |
| |
| export class A implements mainInterface { |
| init(): void { |
| $('div#content').html('a'); |
| } |
| } |
b.ts
| import { mainInterface } from './main.interface'; |
| import $ from 'jquery'; |
| |
| export class B implements mainInterface { |
| init(): void { |
| $('div#content').html('b'); |
| } |
| } |
N.html
對應 N.ts
,將所有要對應的 class 設定加到 routes.ts
,main.ts
會動態偵測到 html 檔案的 body 有沒有相對應的 id,有的話就去撈相對應的 class,而相對應的 class 繼承 interface 一定要有 init()
這個 method,最為這個頁面時要做的預設事件,這樣 compile 的結果 jQuery
或其他的套件只會有一份,並且做到隔離不同頁面所需要的功能。