当前位置: 首页 > 知识库问答 >
问题:

编写TypeScript并为浏览器和节点发出库

陈瀚
2023-03-14

我在Node.js和browser中使用了一个内部库。它有许多文件,连接着一个Grunt任务和不同的序言,一个用于浏览器,一个用于节点:

浏览器:

// dependent 3rd-party libs like Mustache are already global
window.myLib = { /*just a namespace object filled with stuff later*/ }

// then comes the plain javascript which just adds elements to myLib.
// This part is identical to that used in Node
// example:
myLib.renderPartDetail = function (...) {...};

节点:

var Mustache = require('mustache');
var myLib = {};
module.exports = myLib;

// then comes the plain javascript which just adds elements to myLib.
// This part is identical to that used in Browser

这导致2个不同的单一输出js文件,一个用于浏览器,一个用于节点。

我想要什么

  • 使用打字脚本
  • 如果可能,对浏览器和节点仅使用一种CommonJS语法(或ES6模块)
  • 投资于未来几个月不会死亡的东西
  • 更模块化一点(可能有人只需要lib的一部分)

是什么让我困惑

我发现2种不同类型的模块处理在TypeScript:

import {a, b} from './x'

import c = require('./y')

我习惯了后者从节点,但第一个看起来像ES6(这可能是未来)。

目前我使用的是tsc--modulecommonjs,但这只是输出格式,对吗?还有--模块系统,但我找不到该选项的文档,当我使用它时,编译器会抱怨导出=…是不允许的。

还没有玩过浏览器代码tsifyWatchifyjspm,SystemJS,webpack-这太相似了,太多了,但我认为其中一个或几个工具可以为我做这项工作。

当我需要(

具体问题

  • 我应该在代码中使用哪种模块语法才能最好地使用节点和浏览器?
  • 哪个工具链可以解决我的需求?是否有我可以复制的示例项目或样板文件?(我也可以大口大口地喝,不用咕噜声)。
  • 当前支持哪些类型脚本和节点版本?我在IntelliJ中嵌入了1.4,当将1.6.2作为外部引用时,我得到了非常深刻的错误消息,比如“TypeError:host.fileExists不是一个函数”(没有找到任何有用的信息)。也许使用节点v4.1.1不是最佳选择

很抱歉,这篇文章太复杂了。如果有必要,请告诉我从哪里开始,或者最重要的改变是什么,或者从什么开始。


共有3个答案

谷博艺
2023-03-14

这是我用webpack和Babel得到它的方式:

我的index.ts文件位于src文件夹中

package.json

{
  "scripts": {
    "bundle-dev" : "rimraf dist && tsc --outDir dist/temp && webpack --env.development --display-error-details && rimraf dist/temp",
    "bundle-prod": "rimraf dist && tsc --outDir dist/temp && webpack --env.production  --display-error-details && rimraf dist/temp"
  },
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/plugin-transform-reserved-words": "^7.10.4",
    "@babel/plugin-transform-typescript": "^7.11.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "@babel/plugin-syntax-flow": "^7.10.4",
    "@babel/preset-env": "^7.11.5",
    "babel-loader": "^8.1.0",
    "esmify": "^2.1.1",
    "rimraf": "^3.0.2",
    "ts-loader": "^8.0.4",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.7",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "AMD",
    "target": "ES5",
    "declaration": true,
    "outDir": "dist/my-javascript-package",
    "moduleResolution": "node"
  },
  "exclude": [
    "node_modules"
  ],
  "include": [
    "src/**/*"
  ]
}

B.法律改革委员会

{
    "plugins": [
        "transform-class-properties",
        "@babel/plugin-syntax-flow",
        "@babel/plugin-transform-reserved-words",
        "@babel/plugin-transform-typescript"
    ]
}

webpack.config.js

const path = require('path');

module.exports = env => {
    const mode = env.production ? 'production' : 'development';

    const config = (target) => {
        return {
            entry: {
                index: './src/index.ts'
            },
            target: target,
            output: {
                path: path.resolve(__dirname, "dist/my-javascript-package"),
                filename: target+'.js',
                library: 'MyJavaScriptPackage',
                libraryTarget: "umd",
                umdNamedDefine: true,
                globalObject: 'this',
            },
            plugins: [
                new (require('webpack')).DefinePlugin({
                    'process.env.NODE_ENV': JSON.stringify(mode)
                }),
            ],
            mode: mode,
            resolve: {
                extensions: ['.ts', '.js', '.json']
            },
            module: {
                rules: [
                    {
                        test: /\.ts$/,
                        exclude: /node_modules/,
                        use: [
                            {
                                loader: "babel-loader",
                                options: {
                                    presets: [
                                        [
                                            "@babel/preset-env",
                                            {
                                                "targets": {
                                                    "browsers":["last 2 versions"],
                                                    "node":"current"
                                                }
                                            }
                                        ]
                                    ],
                                },
                            },
                            {
                                loader: "ts-loader",
                            },
                        ],
                    },
                ],
            },
        };
    };

    return [config('node'), config('web')]
};

捆绑它

npm run bundle-dev

或者

npm run bundle-prod 

进口

import {MyJavaScriptPackage} from "my-javascript-package/node";
//or 
import {MyJavaScriptPackage} from "my-javascript-package/web"; // SPA example

参考资料:

  • https://itnext.io/how-to-build-and-publish-npm-packages-with-webpack-dea19bb14627
  • https://webpack.js.org/concepts/
  • https://stackoverflow.com/a/46633682/4508758
  • https://stackoverflow.com/a/49639482/4508758
  • https://stackoverflow.com/a/52092788/4508758
  • https://stackoverflow.com/a/51737190/4508758
  • 及其他
蒋畅
2023-03-14

我也有TypeError:host.fileWebStorm 10和自定义TypeScript编译器(通过npm安装)存在错误。

然而,这在WebStorm 11(2015年11月2日发布)中得到了修复https://www.jetbrains.com/webstorm/download/

红存
2023-03-14

我应该在代码中使用哪个模块语法来最好地使用节点和浏览器?

如果您的目标是es5,那么这两个语法将向下编译,以有效地实现相同的功能。使用任何一种,都可以随意混合搭配。

哪个工具链可以解决我的需求?是否有我可以从中复制的示例项目或样板

我使用(并推荐)webpack。你可以像现在这样使用通用/nodejs,然后webpack可以为前端创建捆绑包。有关示例,请参见https://github.com/basarat/tsb/tree/master

当前支持哪些类型脚本和节点版本?我在IntelliJ中嵌入了1.4,当将1.6.2作为外部引用时,我得到了非常深刻的错误消息,比如“TypeError:host.fileExists不是一个函数”(没有找到任何有用的信息)。也许使用节点v4.1.1不是最佳选择?

使用最新的TypeScript(TypeStrong提供的各种工具,例如atom TypeScript/grunt ts/ts loader支持该工具)。您得到的错误是webstorm错误,应该向他们报告。(我使用atom类型脚本)。

 类似资料:
  • 我正在尝试创建一个可以被web应用程序或其他节点模块使用的npm包。 如果我只支持浏览器,我只会分配给window

  • 现在如何将此保存到浏览器。

  • 我使用以下命令在同一台计算机上启动了集线器和节点: 我尝试使用以下代码实例化一个浏览器窗口: 页面获取成功,我可以使用browser.page看到页面的超文本标记语言代码_source但是节点上的Chrome窗口没有打开。我根本没有指定无头选项。我使用的是95版Chrome和Chromedrive。 请注意,我是在jupyter笔记本上运行代码的,该笔记本托管在充当selenium服务器和节点的同

  • 但是当我执行上面的脚本时,我会得到以下错误: Message:StaleElementReferenceException:Message:Element不再附加到DOM StackTrace:at fxdriver.cache.getElementat(资源://fxdriver/modules/web-element-cache.js:9351)at utils.getElementat(文件

  • 问题内容: 我如何在客户端使用 HTML5 , CSS 和 JavaScript 编写网站,以便 在页面加载后 允许 客户端浏览器之间的直接tcp / ip连接 。 我需要这样做以减少延迟,因为该站点将要求将其中一个用户的输入尽快传输给另一用户,因此从客户端A到服务器再向客户端B发送数据并不是一个好习惯。选项。 我阅读了有关此主题的先前文章,但没有可用的解决方案/示例。据我了解,可以使用Silve

  • 我最近在本地网络上的机器上安装了Sonarqube5.1。我已经成功地在我的一个项目上运行了Maven插件,一切似乎都很好。我还从市场上安装了Eclipse插件(Luna),并且能够在Eclipse中运行分析。这些问题显示在视图中。但是,和都是完全空白的。 这似乎与这篇文章相似,但那里引用的bug已经被标记为已修复。我会贴一张截图,但我没有所需的声誉。 还有人遇到过这个吗?