Vyhledávání na webu

javascript - Jak obecně importuji knihovny v TypeScriptu?


Jsem nový v TypeScriptu a právě se do toho nořím. Myslím, že koncept zatím chápu, ale tomu, čemu nerozumím, je, jak nakonec využít knihovny (v mém případě D3 pro manipulaci se SVG DOM). Ve vanilla JavaScriptu jsem to jednoduše dělal staromódním způsobem tím, že jsem zahrnul knihovnu a můj hlavní skript main.js jeden po druhém, ale jak můj projekt roste, chci využít výhody TypeScriptu s modulárním přístupem.

Aktuální problém je tato chyba prohlížeče (Chrome):

Nezachycená TypeError: Nepodařilo se vyřešit specifikátor modulu „d3“. Relativní odkazy musí začínat buď „/“, „./“ nebo „../“

No, vím, že to ukazuje na můj příkaz importu, ale nemohu přijít na to, jak to vyřešit.

tsconfig.json

    {
        "compilerOptions": {
            "target": "ES5",'ESNEXT'. */
            "module": "ESNext",
            "declaration": true,
            "outDir": "./dist/fgn/",
            "rootDir": "./src/fgn/",
            "strict": true,
            "allowSyntheticDefaultImports": true,
            "esModuleInterop": true,
            "skipLibCheck": true, // required to avoid checking d3 type definitions
            "forceConsistentCasingInFileNames": true
        }
        // ,"files": [],
        // "include": [],
        // "exclude": []
    }

index.html (úryvek)

    <head>
        <script src="../dist/fgn/fgn.js" type="module"></script>
    </head>
    <body>
        <button id="testButton" onClick="unreachableFoo();">Test Script</button>
    </body>

./src/fgn/fgn.ts

    /*  Assuming I want to use the whole library. That's how it is documented by Mike Bostock.
        However, this import statement throws an error in the browser (tested in Chrome, Firefox)
        when being transpiled to javascript */
    import * as d3 from "d3"; // points to '[root]/node_modules/@types/d3' (index.d.ts)

    console.log('script is running...');

    // This is the desired functionality I want to gain: having access to d3 from global namespace (globalThis ?)
    d3.select('#testButton').on('click', () => {alert('button clicked!');});

    // Also this is not working. The browser complains the function is not defined.
    function unreachableFoo() { console.log('foo'); }

Zkoušel jsem několik nastavení tsconfig a změnil import tak, aby ukazoval na "[root]/node_modules/d3/" (index.js) při povolení "allowJs" v tsconfig, ale to vedlo k dalším problémům, protože tsc nějak zahrnul cestu node_modules/@types/, což způsobilo zmatení a chyby s deklaracními soubory tam.

Další pokus byl použít webpack, nastavit package.json a vybudovat závislosti odtud. Možná jdu tím směrem správně, ale chyba v prohlížeči tam stále byla.

Co mi chybí?

Odpověď č. 1

Rozumím,

Jednoduše jsem přeskočil krok s browserify. Místo webpacku nyní používám Rollup. Pro všechny, kdo narazí na podobné obtíže při začátcích s tímto tématem, zde je několik dobrých vysvětlení (věnujte čas sledování každého z nich):

Jak nastavit projekt TypeScript pomocí Rollup.js -- instalace Rollup a potřebné nastavení tsconfig.json; ne všechny navrhované instalace však jsou nutné.

Chybějící názvy globálních proměnných #162 -- nastavení rollup.config.js

@rollup/plugin-node-resolve -- použití tohoto pluginu, navíc

Oficiální dokumentace rollup.js -- Přečtěte si manuál

Nicméně specifická pole Rollupu v souboru rollup.config.js se časem změnila, např. atribut 'entry' byl přejmenován na 'input'. Zde je moje současná konfigurace podle výše uvedených návodů:

/* buil-in */
import resolve from '@rollup/plugin-node-resolve';
/*  Install both plugins:
    npm i @rollup/plugin-babel @rollup/plugin-commonjs --save-dev
*/
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';

export default [
    {
        input: 'src/scripts/main.js', // change this accordingly
        plugins: [
            resolve({
                jsnext: true,   
                main:   true,
                browser:true,         
            }),
            commonjs(),
            babel({
                exclude: 'node_modules/**',
            })
        ],
        output: {
            name: 'main',
            file: 'public/scripts/main.js', // change this accordingly
            /*  format: 'iife' wraps everything into a self-executing function
                (function () { ... }());
            */
            format: 'iife' // or 'cjs'
        }
    }
];

To ale zatím kód nezmenšuje. Je to jen vývojové nastavení, ale můžete přidat i produkční.

build skript v package.json

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tsc -b && rollup -c rollup.config.js"
  }

Odpověď č. 2

Vítejte! Dokumentace k D3 bude trochu těžší sledovat, protože používá příkaz import pro JS a ne TS. Zkuste změnit svůj příkaz import na

import { *desired methods* } from 'd3'; // there is no default d3 export

Také budete chtít vrátit zpět své změny v souboru tsconfig.