如何在打字稿编译器中声明节点导入以在编译文件中忽略它?

how to declare a node import in typescript compiler to ignore it in compiled file?

你好,在尝试理解 typescripttypescript 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 文件中不需要。第二个导入行导入一个名为 graphUrlvariable 作为 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'; 行。