如何在打字稿编译器中声明节点导入以在编译文件中忽略它?
how to declare a node import in typescript compiler to ignore it in compiled file?
你好,在尝试理解 typescript
和 typescript compiler
时我尝试了一个小网络项目。
工作流程很简单。 typescript compiler
监视 src/js
文件夹并将每个 *.ts
文件作为 *.js
文件编译到我的 dev_static/js
文件夹中,并复制文件夹结构。
如果需要,我的 django dev server
从那里获取 *.js
文件。例如 page_1.html
需要脚本 <script type="module" src="{% static 'js/pages/page_1.js' %}"> </script>
.
src/
js/
pages/page_1.ts
pages/page_2.ts
navbar/navbar.ts
modules/some_modul.ts
dev_static/
js/
pages/page_1.js
pages/page_2.js
navbar/navbar.js
modules/some_modul.js
.tsconfig
{
"compilerOptions": {
"outDir": "../dev_static/js",
"removeComments": true,
"target": "ES6",
"lib": [
"es6",
"dom",
"es2015.promise"
],
"allowJs": true,
"checkJs": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"~*": ["./*"],
"@node/*": ["./node_modules/*"]
},
},
// Input Dir
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
问题
将模块导入为 ES6 工作正常。但是我正在努力在我的打字稿项目中声明像 Axios 这样的第三方库。例如,要使用 axios 的类型和智能感知,我将 Axios 作为节点模块导入,如下所示:
axios_fetch.ts
import axios from '@node/axios';
import { graphUrl } from '../env/env.js';
编译器输出:
axios_fetch.js
import axios from '@node/axios';
import { graphUrl } from '../env/env.js';
浏览器当然不知道如何解决这个问题:import axios from '@node/axios';
.
2127.0.0.1/:1 Uncaught TypeError: Failed to resolve module specifier "@node/axios". Relative references must start with either "/", "./", or "../".
此外,我在我的开发服务器中加载了全局的 axios
min.version(或其他第 3 方库)。它嵌入在一个基本模板中,每个其他页面都基于该模板,默认情况下每个页面都会有 <script type="module" src="{% static 'js/3rdParty/axios/axios.min.js' %}"> </script>
。
dev_static/
js/
pages/page_1.js
<...>
3rdParty/axios/axios.min.js
问题
我如何告诉编译器不要编译我的 typescript 文件中的 import axios from '@node/axios';
行?因为 Axios 库将在我的所有页面(模板)中作为缩小版本可用或全局加载。我只需要这一行,这样打字稿就不会抱怨并且有可用的类型。
我需要的是 typescript compiler
在编译时不处理 axios 的“导入”行。或者换句话说,我只需要在开发编译时导入节点以进行类型检查、接口等,但不需要在完成的 javascript 文件或运行时导入。
axios_fetch.ts
import axios from '@node/axios';// do not compile this. "axios" will be global available
import { graphUrl } from '../env/env.js';
如果我在我的 axios_fetch.js
中手动删除 import axios from '@node/axios';
就可以了。
好吧,经过几天的研究,我找到了这个解决方案,它对我有用。
Typescript 不再抱怨或将类型 import
行导出到我的编译文件中,同时仍然可以访问我的 *.ts
文件中的类型和智能感知。
首先我在tsconfig.json
中做了一点改动,声明"importsNotUsedAsValues":"remove"
非常重要。
tsconfig.json
{
"compilerOptions": {
// Output Dir
"outDir": "../dev_static/js",
"removeComments": true,
// Compile to. What JS Versions.
"target": "ES6",
"lib": [
"es6",
"dom",
"es2015.promise"
],
// allows also normal JS files
"allowJs": true,
// Normal JS file also be checked
"checkJs": true,
// important for import modules etc.
"module": "es2015",
"moduleResolution": "node",
"importsNotUsedAsValues":"remove",
"baseUrl": ".",
"paths": {
"~*": ["./*"],
"@node/*": ["./node_modules/*"]
},
"types": ["axios"]
},
// Input Dir
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
然后我只从 axios nodes 版本中导入了需要的类型,并将其声明为全局的。但您也可以从 axios git 存储库下载 index.d.ts
类型的文件并将其放入您的文件夹。从 tsconfig
中删除 "types": ["axios"]
并使用 import {AxiosStatic} from './axios';
导入
换句话说,第一行导入了 types
,我只需要在这个 *.ts
文件中使用,但稍后在我编译的 *.js
文件中不需要。第二个导入行导入一个名为 graphUrl
的 variable
作为 ES6 模块,另一方面,我稍后将在编译文件中需要该引用。
axios_fetch.ts
import { AxiosStatic } from 'axios'; // import the specific types from nodes axios
import { graphUrl } from '../env/env.js'; // that some es6 module vars i need also later
declare global {
const axios: AxiosStatic ;
}
// AXIOS Client
export const clientA = axios.create({
baseURL: graphUrl,
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
} });
所以通过 declare global
typescript 似乎不必担心不导出 const axios: AxiosStatic
或满足所有类型需求 (importsNotUsedAsValues
) 因为它现在知道会有押金全球规模。
axios_fetch.js
import { graphUrl } from '../env/env.js';
const csrftoken = getCookie(cookieName);
export const clientA = axios.create({
baseURL: graphUrl,
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
}
});
现在编译时没有类型的 import { AxiosStatic } from 'axios';
行。
你好,在尝试理解 typescript
和 typescript compiler
时我尝试了一个小网络项目。
工作流程很简单。 typescript compiler
监视 src/js
文件夹并将每个 *.ts
文件作为 *.js
文件编译到我的 dev_static/js
文件夹中,并复制文件夹结构。
如果需要,我的 django dev server
从那里获取 *.js
文件。例如 page_1.html
需要脚本 <script type="module" src="{% static 'js/pages/page_1.js' %}"> </script>
.
src/
js/
pages/page_1.ts
pages/page_2.ts
navbar/navbar.ts
modules/some_modul.ts
dev_static/
js/
pages/page_1.js
pages/page_2.js
navbar/navbar.js
modules/some_modul.js
.tsconfig
{
"compilerOptions": {
"outDir": "../dev_static/js",
"removeComments": true,
"target": "ES6",
"lib": [
"es6",
"dom",
"es2015.promise"
],
"allowJs": true,
"checkJs": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"~*": ["./*"],
"@node/*": ["./node_modules/*"]
},
},
// Input Dir
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
问题
将模块导入为 ES6 工作正常。但是我正在努力在我的打字稿项目中声明像 Axios 这样的第三方库。例如,要使用 axios 的类型和智能感知,我将 Axios 作为节点模块导入,如下所示:
axios_fetch.ts
import axios from '@node/axios';
import { graphUrl } from '../env/env.js';
编译器输出:
axios_fetch.js
import axios from '@node/axios';
import { graphUrl } from '../env/env.js';
浏览器当然不知道如何解决这个问题:import axios from '@node/axios';
.
2127.0.0.1/:1 Uncaught TypeError: Failed to resolve module specifier "@node/axios". Relative references must start with either "/", "./", or "../".
此外,我在我的开发服务器中加载了全局的 axios
min.version(或其他第 3 方库)。它嵌入在一个基本模板中,每个其他页面都基于该模板,默认情况下每个页面都会有 <script type="module" src="{% static 'js/3rdParty/axios/axios.min.js' %}"> </script>
。
dev_static/
js/
pages/page_1.js
<...>
3rdParty/axios/axios.min.js
问题
我如何告诉编译器不要编译我的 typescript 文件中的 import axios from '@node/axios';
行?因为 Axios 库将在我的所有页面(模板)中作为缩小版本可用或全局加载。我只需要这一行,这样打字稿就不会抱怨并且有可用的类型。
我需要的是 typescript compiler
在编译时不处理 axios 的“导入”行。或者换句话说,我只需要在开发编译时导入节点以进行类型检查、接口等,但不需要在完成的 javascript 文件或运行时导入。
axios_fetch.ts
import axios from '@node/axios';// do not compile this. "axios" will be global available
import { graphUrl } from '../env/env.js';
如果我在我的 axios_fetch.js
中手动删除 import axios from '@node/axios';
就可以了。
好吧,经过几天的研究,我找到了这个解决方案,它对我有用。
Typescript 不再抱怨或将类型 import
行导出到我的编译文件中,同时仍然可以访问我的 *.ts
文件中的类型和智能感知。
首先我在tsconfig.json
中做了一点改动,声明"importsNotUsedAsValues":"remove"
非常重要。
tsconfig.json
{
"compilerOptions": {
// Output Dir
"outDir": "../dev_static/js",
"removeComments": true,
// Compile to. What JS Versions.
"target": "ES6",
"lib": [
"es6",
"dom",
"es2015.promise"
],
// allows also normal JS files
"allowJs": true,
// Normal JS file also be checked
"checkJs": true,
// important for import modules etc.
"module": "es2015",
"moduleResolution": "node",
"importsNotUsedAsValues":"remove",
"baseUrl": ".",
"paths": {
"~*": ["./*"],
"@node/*": ["./node_modules/*"]
},
"types": ["axios"]
},
// Input Dir
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
然后我只从 axios nodes 版本中导入了需要的类型,并将其声明为全局的。但您也可以从 axios git 存储库下载 index.d.ts
类型的文件并将其放入您的文件夹。从 tsconfig
中删除 "types": ["axios"]
并使用 import {AxiosStatic} from './axios';
换句话说,第一行导入了 types
,我只需要在这个 *.ts
文件中使用,但稍后在我编译的 *.js
文件中不需要。第二个导入行导入一个名为 graphUrl
的 variable
作为 ES6 模块,另一方面,我稍后将在编译文件中需要该引用。
axios_fetch.ts
import { AxiosStatic } from 'axios'; // import the specific types from nodes axios
import { graphUrl } from '../env/env.js'; // that some es6 module vars i need also later
declare global {
const axios: AxiosStatic ;
}
// AXIOS Client
export const clientA = axios.create({
baseURL: graphUrl,
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
} });
所以通过 declare global
typescript 似乎不必担心不导出 const axios: AxiosStatic
或满足所有类型需求 (importsNotUsedAsValues
) 因为它现在知道会有押金全球规模。
axios_fetch.js
import { graphUrl } from '../env/env.js';
const csrftoken = getCookie(cookieName);
export const clientA = axios.create({
baseURL: graphUrl,
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken,
}
});
现在编译时没有类型的 import { AxiosStatic } from 'axios';
行。