【问题标题】:Write TypeScript and emit a library for Browser and Node编写 TypeScript 并为 Browser 和 Node 生成一个库
【发布时间】:2015-12-26 19:09:46
【问题描述】:

我有一个用于 Node.js 和浏览器的内部库。它有很多文件,连接着一个 Grunt 任务和不同的序言,一个用于浏览器,一个用于 Node:

浏览器:

// 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 文件,一个用于浏览器,一个用于 Node。

我想要什么

  • 使用 TypeScript
  • 如果可能,对浏览器和节点只使用一种 CommonJS 语法(或 ES6 模块)
  • 投资一些不会在未来几个月内死亡的东西
  • 更加模块化(也许有人只需要部分库)

什么让我困惑

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

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

和

import c = require('./y')

我习惯了后者来自 node,但第一个看起来像 ES6(可能是未来)。

目前我使用tsc --module commonjs,但这只是输出格式,对吧?还有--module system,但我找不到这个选项的文档,当我使用它时,编译器抱怨export = ... is not allowed。

还没有玩过browserify、tsify、watchify、jspm、SystemJS、webpack - 它太相似了,太多了,但我认为其中一个或几个工具可以为我做这项工作。

当我require(<a node module living in node_modules>) 时,tsc 找不到模块:“TS2307:找不到外部模块'moment'”。

具体问题

  • 我应该在我的代码中使用哪种模块语法来最好地使用 Node 和 Browser?
  • 哪个工具链可以解决我的需求?是否有可以从中复制的示例项目或样板文件? (我也对 Gulp 持开放态度,不必使用 Grunt)。
  • 目前支持哪些 TypeScript 和 Node 版本?我在 IntelliJ 中嵌入了 1.4,当将 1.6.2 作为外部引用时,我收到了非常深奥的错误消息,例如“TypeError:host.fileExists 不是函数”(没有发现任何有用的信息)。也许使用 Node v4.1.1 不是最佳选择?

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

【问题讨论】:

    标签: javascript node.js typescript browserify webpack


    【解决方案1】:

    我应该在我的代码中使用哪种模块语法最适合 Node 和浏览器?

    如果您以es5 为目标,那么这两种语法都会编译成有效的相同内容。使用任何一种,并随意混合搭配。

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

    我使用(并推荐)webpack。您可以按原样使用 commonjs / nodejs,然后 webpack 可以为前端创建包。示例见https://github.com/basarat/tsb/tree/master

    目前支持哪些 TypeScript 和 Node 版本?我在 IntelliJ 中嵌入了 1.4,当将 1.6.2 引用为外部时,我收到了非常深奥的错误消息,例如“TypeError:host.fileExists 不是函数”(没有找到任何有用的信息)。也许使用 Node v4.1.1 不是最佳选择?

    使用最新的 TypeScript(TypeStrong 的各种工具,例如 atom-typescript/grunt-ts/ts-loader 支持)。您收到的错误是 webstorm 错误,应该向他们报告。 (我使用 atom-typescript)。

    【讨论】:

    • @basart 你就是那个人,谢谢!我目前正在阅读您的书 TypeScript Deep Dive 并希望尽快学习 TypeScript。我喜欢这本书,谢谢提供!
    • @hgoebl 谢谢。我目前正在业余时间从事 tsb 工作……希望围绕 typescript 的一些好的工作流程会从中产生。目标明年一月?
    • 从 TypeScript 转译代码没有 webpack 生成浏览器就绪的 JavaScript 代码库的最直接方法是什么?
    【解决方案2】:

    WebStorm 10 和自定义 Typescript 编译器(通过 npm 安装)也出现 TypeError: host.fileExists 错误。

    但是,此问题已在 WebStorm 11 中修复(2015 年 11 月 2 日发布) https://www.jetbrains.com/webstorm/download/

    【讨论】:

      【解决方案3】:

      这是我使用 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/**/*"
        ]
      }
      

      .babelrc

      {
          "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
      

      参考资料:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-01
        • 2020-01-19
        • 2019-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多