【问题标题】:Typescript NPM module import causing reference to failTypescript NPM 模块导入导致引用失败
【发布时间】:2017-11-07 15:32:29
【问题描述】:

我对 Typescript 比较陌生(好吧,我多年来一直在尝试使用它,但从未真正理解某些方面)。这个问题一直困扰着我一段时间,与 NPM 导入有关。我正在尝试在 Typescript 中为 dashjs 和 chartjs 使用一些 Web NPM 模块。尝试导入它们然后从运行脚本引用它们时都不起作用。

程序文件似乎看不到 SensedPlayback 类,这意味着某些内容未正确编译,但 SensedPlayback 的 JS 文件已构建。删除 SensedPlayback.ts 文件顶部的 import 允许程序文件看到它,但导入的模块不起作用。模块的智能感知在 SensedPlayback.ts 内工作,表明模块导入工作正常。

任何帮助将不胜感激! 杰拉德

tsconfig.json

{
  "compileOnSave": true,
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "moduleResolution": "node",
    "module": "commonjs",
    "target": "es6",
    "outDir": "wwwroot/js/"
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

SensedPlayback.ts(带导入)

import * as dashjs from "dashjs";

namespace TIMINGSRC {
    export declare var TimingObject: any;
    export declare var MediaSync: any;
}

class SensedPlayback {
    production: Production;

    videosDiv: HTMLDivElement;
    videos: dashjs.MediaPlayerClass[];
    seekHead: HTMLInputElement;
    playBtn: HTMLButtonElement;
    pauseBtn: HTMLButtonElement;

    _playbackTimeReciever: PlaybackTimeSync;

    _timingObject: any;
    _isSeeking: boolean;

    constructor(production: Production, videosDiv: HTMLDivElement, seekHead: HTMLInputElement, playBtn: HTMLButtonElement, pauseBtn: HTMLButtonElement) {
        this.production = production;

        this.videosDiv = videosDiv;
        this.seekHead = seekHead;
        this.playBtn = playBtn;
        this.pauseBtn = pauseBtn;

        this._setupPage();

        this._playbackTimeReciever = new PlaybackTimeSync();
    }

    start() {
        this._playbackTimeReciever.subscribe((tr) => {
            this.loadMediaForTime(tr.start);
        });

        this._playbackTimeReciever.start();
    }

    _setupPage() {
        this.playBtn.addEventListener('click', (event) => {
            this._timingObject.update({ velocity: 1.0 });
        });

        this.pauseBtn.addEventListener('click', (event) => {
            this._timingObject.update({ velocity: 0.0 });
        });

        this.seekHead.addEventListener('mousedown', (event) => {
            this._isSeeking = true;
        });

        this.seekHead.addEventListener('mouseup', (event) => {
            this._timingObject.update({ position: this.seekHead.value });
            this._isSeeking = false;
        });
    }

    loadMediaForTime(time: Date) {
        let takes = this.production.takes.filter((t) => {
            t.media.some((m) => m.startTime >= time
                && new Date(m.startTime.setMilliseconds(m.startTime.getMilliseconds() + m.duration)) < time)
        });

        let take = takes[0];
        this.videos = [];
        this.videosDiv.innerHTML = "";

        for (var m of take.media) {
            let video = <HTMLVideoElement>(document.createElement("video"));
            var player = new dashjs.MediaPlayerClass();
            player.initialize(video, URL.createObjectURL(`${m.url}/playback.mpd`), false);

            let wrapper = <HTMLDivElement>(document.createElement("div"));
            wrapper.classList.add("col-md-4");
            wrapper.classList.add("col-sm-6");

            let heading = <HTMLHeadingElement>(document.createElement("h4"));
            heading.innerText = this.production.cameras.find((c) => { return c.id == m.cameraId }).name;

            wrapper.appendChild(heading);
            wrapper.appendChild(video);

            this.videosDiv.appendChild(wrapper);
            this.videos.push(player);
        }

        this._configurePlayers();
    }

    _configurePlayers() {
        for (var v of this.videos) {
            v.on('loadstart', function (event) {
                v.setMaxAllowedBitrateFor('video', 4600);
            });

            v.on('loadedmetadata', (event) => {
                if (this._timingObject === undefined) {
                    this._timingObject = new TIMINGSRC.TimingObject({ range: [0, event.target.duration] });
                    this.seekHead.min = '0';
                    this.seekHead.step = '0.25';
                    this.seekHead.max = `${v.duration()}`;
                    this._timingObject.on('timeupdate', () => {
                        if (!this._isSeeking) {
                            this.seekHead.value = this._timingObject.clock.now();
                        }
                    });
                }
                var sync = new TIMINGSRC.MediaSync(event.target, this._timingObject);
            });
        }
    }
}

SensedPlaybackProgram.ts

let videosDiv = <HTMLDivElement>document.getElementById('cameras');
let seekHead = <HTMLInputElement>document.getElementById('seekhead');
let playBtn = <HTMLButtonElement>document.getElementById('play');
let pauseBtn = <HTMLButtonElement>document.getElementById('pause');

let production : Production = JSON.parse((<HTMLInputElement>document.getElementById('production')).value);

let playback = new SensedPlayback(production, videosDiv, seekHead, playBtn, pauseBtn);

playback.start();

【问题讨论】:

    标签: typescript npm


    【解决方案1】:

    当您编译一系列不使用importexport 的文件时,这些文件将被视为不是模块,并且它们声明的所有符号最终都位于全局空间中。这就是为什么当您删除 import 语句时,SensedPlaybackProgram.ts 能够看到 SensedPlayback,即使它是在 SensedPlayback.ts 中定义的

    当你在SensedPlayback.ts 中添加你的import 语句时,你把它变成一个 TypeScript 模块,然后形成,如果你想使用它定义的符号,你需要从这个模块中导出它,然后导入您要在其中使用它的符号。所以修改SensedPlayback.ts有:

    export class SensedPlayback {
    ...
    

    SensedPlaybackProgram.ts 中,使用以下命令导入:

    import { SensedPlayback } from "./SensedPlayback";
    

    (根据需要调整路径。)

    【讨论】:

    • 完美就是问题所在。这总是让我对 Typescript 感到沮丧。诚然,对内部运作知之甚少,但似乎会发生类似这样的晦涩难懂的事情。对我来说,这似乎是一个黑匣子,添加导入语句如何更改文件的打包,而没有清楚地告诉你这是发生了什么。无论如何感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 2019-04-28
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    相关资源
    最近更新 更多