淺談TypeScript 用 Webpack/ts-node 運(yùn)行的配置記錄
公司項(xiàng)目代碼是用 TypeScript 寫(xiě)的, 中間遇到有些代碼不要放到 Node 里面去跑.
具體場(chǎng)景一些路由配置, 比較大的一塊 JSON 數(shù)據(jù)定義在 TypeScript 里.
我另外有增加腳本, 基于這些 JSON 數(shù)據(jù)用來(lái)生成切換路由的函數(shù).
這就需要運(yùn)行 TypeScript 了, 而且可能包含一些額外的業(yè)務(wù)代碼.
首先 Node 運(yùn)行 TypeScript 有提供 ts-node 用來(lái)處理.
ts-node 會(huì)先編譯 TypeScript 代碼到 JavaScript, 再調(diào)用 Node 運(yùn)行.
不過(guò)這個(gè)辦法有一些問(wèn)題, 一個(gè)是 TypeScript 定義的路徑配置不成功,
另一個(gè)問(wèn)題更麻煩點(diǎn), 就是引用到的其他的瀏覽器端代碼因?yàn)橛|發(fā)運(yùn)行而引起報(bào)錯(cuò).
Webpack 打包 TypeScript Node 代碼
我先想到了一個(gè)相對(duì)省事的方案, 就是用 Webpack 對(duì) TypeScript 進(jìn)行打包.
打包完成以后輸出 JavaScript 代碼. 而瀏覽器代碼打包進(jìn)去, 但不一定運(yùn)行.
由于 TypeScript 配置在 Webpack 當(dāng)中引用有比較成熟的方案, 整個(gè)配置也寫(xiě)好:
module.exports = {
mode: "development",
target: "node",
entry: ["./example/gen-router.ts"],
output: {
filename: "gen-router.js",
path: path.join(__dirname, "../", distFolder),
},
devtool: "none",
module: {
rules: [
// 正常的 TypeScript 編譯方式, 我這份是拷貝的.
{
test: /\.tsx?$/,
exclude: [/node_modules/, path.join(__dirname, "scripts")],
use: [
{ loader: "cache-loader" },
{
loader: "thread-loader",
options: {
workers: require("os").cpus().length - 1,
},
},
{
loader: "ts-loader",
options: {
happyPackMode: true,
transpileOnly: true,
},
},
],
},
],
},
// Node 模塊, 寫(xiě)在 external 里面表明不需要進(jìn)行打包. 注意 commonjs 前綴
externals: {
prettier: "commonjs prettier",
"@jimengio/router-code-generator": "commonjs @jimengio/router-code-generator",
fs: "commonjs fs",
path: "commonjs path",
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
modules: [path.join(__dirname, "example"), "node_modules"],
// 引用 Plugin 用于讀取 tsconfig.json 文件的配置
plugins: [new TsconfigPathsPlugin({ configFile: path.join(__dirname, "../tsconfig.json") })],
},
};
基于這個(gè)配置打包以后, TypeScript 的代碼被打包好, 并且引用響應(yīng)的 Node 模塊.
運(yùn)行就滿足需求了.
這個(gè)方式對(duì)于其他的服務(wù)端渲染的 TypeScript 代碼打包也是類(lèi)似的.
一些特殊的依賴(lài)如果不好處理, 可以放在 Webpack 當(dāng)中進(jìn)行打包和映射, 得到 js.
ts-node 運(yùn)行
Webpack 配置相對(duì)直接運(yùn)行 TypeScript 來(lái)說(shuō)會(huì)復(fù)雜一點(diǎn), 所以還是 ts-node 簡(jiǎn)單.
在依賴(lài)少的項(xiàng)目當(dāng)中, 我改成了用 ts-node 來(lái)進(jìn)行編譯運(yùn)行. 配置如下
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"sourceMap": true,
"noImplicitAny": false,
"noImplicitThis": true,
"strictNullChecks": false,
"moduleResolution": "node",
// Node 當(dāng)前還沒(méi)有支持直接運(yùn)行 import/export 語(yǔ)法, 需要編譯到 CommonJS
"module": "commonjs",
"target": "es2016",
"jsx": "react",
"lib": ["es2016"],
"types": ["node"],
"baseUrl": "./example/",
"paths": {
"models": ["./example/models"]
},
"plugins": []
}
}
其實(shí)主要修改就 commonjs 那一行, 然后就是加上參數(shù)運(yùn)行
ts-node -P tsconfig-node.json -r tsconfig-paths/register example/gen-router.ts
注意命令當(dāng)中的 tsconfig-paths. 這里的 -r 是指定 register.
ts-node 是先進(jìn)行編譯再運(yùn)行的, 但是引用的路徑?jīng)]有全都替換掉.
比如我在 tsconfig.json 里設(shè)置了 baseUrl 然后內(nèi)部引用是簡(jiǎn)寫(xiě)的, a/b/c,
拿到 Node 本身去運(yùn)行的時(shí)候是不知道這個(gè) a/b/c 對(duì)應(yīng)到哪里,
所以 tsconfig-paths/register 就提供 Node 運(yùn)行時(shí)的方案, 動(dòng)態(tài)查找依賴(lài).
至少這樣 Node register 改寫(xiě)以后, 查找模塊就能正確進(jìn)行了.
其他
另外 TypeScript 編譯 import 語(yǔ)法時(shí)會(huì)產(chǎn)生一個(gè) .default 屬性.
對(duì)于 CommonJS 的模塊, 這個(gè) .default 屬性是多余的. 所以引用的寫(xiě)法要做調(diào)整.
import * as fs from "fs"; import * as path from "path"; import * as prettier from "prettier";
這個(gè)可能跟 tsconfig.json 里其他的配置有關(guān)聯(lián), 我沒(méi)繼續(xù)深挖.
整體的代碼參考 https://github.com/jimengio/meson-form/pull/62/files
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 在Node.js中使用TypeScript的方法示例
- typescript在node.js下使用別名(paths)無(wú)效的問(wèn)題詳解
- 使用nodejs?+?koa?+?typescript?集成和自動(dòng)重啟的問(wèn)題
- nodemon實(shí)現(xiàn)Typescript項(xiàng)目熱更新的示例代碼
- 手把手教你使用TypeScript開(kāi)發(fā)Node.js應(yīng)用
- TypeScript開(kāi)發(fā)Node.js程序的方法
- 詳解使用Typescript開(kāi)發(fā)node.js項(xiàng)目(簡(jiǎn)單的環(huán)境配置)
- Node.js和Express中設(shè)置TypeScript的實(shí)現(xiàn)步驟
相關(guān)文章
js iframe跨域訪問(wèn)(同主域/非同主域)分別深入介紹
js跨域是個(gè)討論很多的話題。iframe跨域訪問(wèn)也被研究的很透了,本文今天就叨叨兩句,感興趣的朋友可以了解下,就當(dāng)鞏固知識(shí)了,希望本文對(duì)你有所幫助2013-01-01
web頁(yè)面和微信小程序頁(yè)面實(shí)現(xiàn)瀑布流效果
這篇文章主要介紹了web頁(yè)面和微信小程序頁(yè)面實(shí)現(xiàn)瀑布流效果,本文通過(guò)實(shí)例代碼圖文介紹,給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-09-09
JS實(shí)現(xiàn)斐波那契數(shù)列的五種方式(小結(jié))
這篇文章主要介紹了JS實(shí)現(xiàn)斐波那契數(shù)列的五種方式(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
JavaScript代碼性能優(yōu)化總結(jié)(推薦)
下面小編就為大家?guī)?lái)一篇JavaScript代碼性能優(yōu)化總結(jié)(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧,祝大家游戲愉快哦2016-05-05
JavaScript學(xué)習(xí)總結(jié)之正則的元字符和一些簡(jiǎn)單的應(yīng)用
這篇文章主要介紹了JavaScript學(xué)習(xí)總結(jié)之正則的元字符和一些簡(jiǎn)單的應(yīng)用,需要的朋友可以參考下2017-06-06
jsp網(wǎng)頁(yè)搜索結(jié)果中實(shí)現(xiàn)選中一行使其高亮
在做搜索結(jié)果時(shí)為了好看需要將選中的行變的高亮些,下面有個(gè)不錯(cuò)的示例,需要的朋友可以參考下2014-02-02
JavaScript使用DeviceOne開(kāi)發(fā)實(shí)戰(zhàn)(二) 生成調(diào)試安裝包
這篇文章主要介紹了JavaScript使用DeviceOne開(kāi)發(fā)實(shí)戰(zhàn)(二) 生成調(diào)試安裝包的相關(guān)資料,需要的朋友可以參考下2015-12-12
javascript之大字符串的連接的StringBuffer 類(lèi)
javascript之大字符串的連接的StringBuffer 類(lèi)...2007-05-05

