繁体   English   中英

在命名空间 Typescript 项目中使用 NPM 模块

[英]Using NPM Modules in Namespaced Typescript project

我有一个项目(现有项目),其前端是在命名空间 typescript 中编写的。我无法将命名空间方法中的所有 typescript 文件重写为导出/导入 es6 语法。

但是下面的代码工作正常。 如果我添加我的新 ts 模块或反应组件,我将它包装在命名空间中,并通过 Class 调用它,或者如果它在其他命名空间中,则使用命名空间前缀调用它,这没有问题。

问题是我不能将外部模块与导入语句一起使用。我该如何使用..?因为导入语句抛出错误。

为了更具体地说明下面的代码,我想使用 react-redux,

当我检查 node_moduels 文件夹时,我看到了引用 React namesapce 的 @types 文件夹,我假设由于 tsconfig 中的这一行

"typeRoots": [
      "./node_modules/@types/"
    ]

但是当我安装npm install --save @types/react-redux时,它还在节点模块的@types 文件夹下创建了 react-redux 文件夹和 index.ts。 但它没有命名空间导出行 React 类型文件如何具有如下所示的内容。

export as namespace React;

declare namespace React {
....
}

最终..我如何在这个项目中使用第三方节点模块,尤其是 react-redux。 或者任何简单的节点模块并在任何 ts 文件中访问它简单的模块,例如“react-bootstrap”下面是包含在 namesapce 中的 react compo.net 的简单 ts 文件 whihc 工作正常(导入 staement 除外)

import { createStore } from 'redux'; //if i add this line this is throwing error.

namespace Profile.Sample {

    import { createStore } from 'redux'; //this too throwing error, without these lines my code is working fine.
    export class Profiles extends React.Component<any> {

        constructor(props) {
            super(props);           
            this.state = { brand: "Ford" };

        }     

        render(): React.ReactNode {

            return (
                <sect
                    <div className="container-fluid">
                        <div className="row">
                            <div className="col-lg-12">
                                <div className="main-title">
                                    <h2>Profiles</h2>
                                    <p>Lorem ipsum dolor sit amet, consectetur adi</p>
                                </div>
                            </div>
                        </div>
                        
                    </div>
                </section>

            );
        }
    }
}

下面是我的 tsconfig

{
  "compileOnSave": true,
  "compilerOptions": {
    "preserveConstEnums": true,
    "experimentalDecorators": true,
    "declaration": true,
    "emitBOM": true,
    "jsx": "react",
    "noEmitHelpers": true,
    "inlineSourceMap": true,
    "inlineSources": true,
    "outFile": "wwwroot/Scripts/site/Profiles.js",
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "target": "es5",
    "typeRoots": [
      "./node_modules/@types/"
    ]
  }
}

我知道名称空间不是未来推荐的方法..但这是一个现有项目,无法将名称空间中的所有文件重写为导入/导出语句。

好的,让我们一步一步让它可以运行:

  1. 虽然你没有明确地 state 它,但我假设你收到错误消息Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'. . 选项outFile生成一个主文件,其中包含所有代码。 由于您在tsconfig.json中使用"target": "es5" ,因此module的默认值为commonjs commonjs是 node.js ( var x = require('x') / exports.x = x ) 广泛使用的模块语法,这种语法不支持将代码合并到一个文件中,因此被禁止。 但是你想在浏览器中使用你的代码,所以那里无论如何都不支持commonjs 所以首先要做的是

    "module": "AMD"插入到您的tsconfig.json文件中。

    AMD 是一种可在浏览器中使用的模块语法。 你也可以使用"UMD" ,它只是一个扩展,所以模块支持AMDcommonjs模块。

  2. 为了避免以后进行更多配置,您还应该

    tsconfig.json文件"outFile": "wwwroot/Scripts/site/Profiles.js"更改为"outDir": "wwwroot/Scripts/site"

  3. module设置为AMD会将moduleResolution的默认值从node更改为classic ,但这并不好,因为这样import {createStore} from 'redux'将失败,并显示错误消息Cannot find module 'redux'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? Cannot find module 'redux'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? . 所以

    "moduleResolution": "node"包含到您的tsconfig.json文件中。

  4. 在您的代码中,您定义了一个 class,它扩展了另一个基数 class。如果您转译这个 inheritance,则需要一个特殊的 function __extends 使用当前设置,此 function 不是由 typescript 生成的,您会收到错误Uncaught ReferenceError: __extends is not defined 所以

    删除"noEmitHelpers": true

  5. 现在您的所有文件都可以转译为 AMD 模块。 但是要使用这些模块,您需要一个模块加载器。 最流行的是require.js 要使用它,

    <script data-main="setup" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" integrity="sha512-c3Nl8+7g4LMSTdrm621y7kf9v3SDPnhxLNhcjFJbKECVnmZHTdo+IRO05sNLTH/D3vA6u1X32ehoLC7WFVdheg==" crossorigin="anonymous"></script>到你的 HTML 文件中。

    您也可以下载并自己使用。 data-main="setup"表示在加载 require.js 之后,执行脚本setup.js 该脚本在下一步中创建。

  6. require.js 需要一些配置才能找到所有模块。 所以

    创建wwwroot\Scripts\site\setup.js

     requirejs.config({ appDir: ".", paths: { 'react': ['./node_modules/react/umd/react.production.min.js', 'https://unpkg.com/react@16/umd/react.production.min'], 'react-dom': ['./node_modules/react-dom/umd/react-dom.production.min.js', 'https://unpkg.com/react-dom@16/umd/react-dom.production.min'], 'redux': ['./node_modules/redux/dist/redux.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min'], }, }); requirejs(['entryPoint'], function() { console.log("Entry point 'index' has been loaded;"); return {}; });

    在第一部分配置 require.js。 特别是,定义了外部模块(通过npm安装的模块)的位置。 此处reactreact-domredux的位置设置为node_modules文件夹中的位置,其中外部文件来自 content delivery.networks (CDN) 作为备份。 您也可以删除其中一个位置。 它们从左到右被请求,如果一个请求失败则继续。 如果您使用node_modules文件夹中的位置,您也必须从您的网络服务器提供它们!

    在第二部分中,模块entryPoint被执行。 这是您的应用程序的入口点。 将名称更改为您希望作为入口点的任何名称。 如果你想让文件someOtherFile.js中定义的模块成为入口点,那么写requirejs(['someOtherFile'], ...

  7. 转译所有文件运行

    tsc --project tsconfig.json

  8. 提供目录wwwroot/Scripts/site中的所有文件,包括您的 HTML 文件。 出于测试目的,您可以使用

    npx serve

你可以在这里看到稍微修改过的代码: https://codesandbox.io/s/elated-fermat-ie2ms?file=/src/index.tsx

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM