我有一个项目(现有项目),它的前端是用名称空间的typescript编写的。我无法从名称空间方法重写所有typescript文件以导出/导入es6语法。
但是,下面的代码运行良好。如果我添加我的新ts模块或react组件,只要我将其封装在命名空间中,并通过Class调用它,或者如果它在其他命名空间中,则使用命名空间前缀调用它,这是没有问题的。
问题是我不能将外部模块与import语句一起使用。我如何使用。。?由于import语句引发错误。
更具体地说,对于下面的代码,我想使用react redux,
当我检查node_moduels文件夹时,我看到了引用React namesapce的@types文件夹我假设由于tsconfig 中的这一行
"typeRoots": [
"./node_modules/@types/"
]
但当我安装npm install --save @types/react-redux
时,它还在节点模块的@types文件夹下创建了带有index.ts的react redux文件夹。但它没有Namespace导出行React类型文件有如下内容。
export as namespace React;
declare namespace React {
....
}
最终。。我该如何使用第三方节点moudles,尤其是在这个项目中使用react redux。或者任何简单节点模块,并在任何ts文件中访问它;react bootstrap";以下是包装在namesapse中的react组件的简单ts文件,该文件运行良好(导入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/"
]
}
}
我知道命名空间不是未来推荐的方法。。但这是一个现有的项目,无法将所有文件从命名空间重写为导入/导出语句。
好的,让我们一步一步地让它运行:
-
虽然您没有明确声明,但我认为您收到了错误消息
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"
,它只是一个扩展,因此该模块支持AMD
和commonjs
模块。 -
为了避免以后进行更多配置,您还应该使用
在
tsconfig.json
文件中将"outFile": "wwwroot/Scripts/site/Profiles.js"
更改为"outDir": "wwwroot/Scripts/site"
-
将
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?
。因此将
"moduleResolution": "node"
包含到tsconfig.json
文件中 -
在代码中,您定义了一个扩展另一个基类的类。如果您转换此继承,则需要一个特殊的函数
__extends
。在当前设置中,此函数不是由typescript生成的,并且您会得到错误Uncaught ReferenceError: __extends is not defined
。因此删除
"noEmitHelpers": true
-
现在,您的所有文件都可以传输到AMD模块。但是要使用这些模块,您需要一个模块加载器。最流行的是require.js。要使用它,
在HTML文件中插入
<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>
您也可以下载并自己提供。
data-main="setup"
表示在加载require.js之后,执行脚本setup.js
。此脚本将在下一步中创建。 -
require.js需要一些配置才能找到所有模块。所以
创建
wwwrootScriptssitesetup.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
安装的模块)的位置。这里,react
、react-dom
和redux
的位置被设置为node_modules
文件夹中的位置,其中来自内容交付网络(CDN)的外部文件作为备份。您也可以删除其中一个位置。它们是从左到右请求的,如果一个请求失败,则继续前进。如果您使用node_modules
文件夹中的位置,您也必须从Web服务器提供这些位置!在第二部分中,执行模块
entryPoint
。这是你的应用程序的入口点。将名称更改为您想要作为入口点的任何名称。如果要将文件someOtherFile.js
中定义的模块作为入口点,请编写requirejs(['someOtherFile'], ...
。 -
要传输所有文件,请运行
tsc --project tsconfig.json
-
提供目录
wwwroot/Scripts/site
中的所有文件,包括您的HTML文件。出于测试目的,您可以使用npx serve
您可以在此处看到稍微修改过的代码:https://codesandbox.io/s/elated-fermat-ie2ms?file=/src/index.tsx.