Importing external JS Library to Angular 2 CLI @Ng

2020-07-24 05:54发布

so I've been using this article to get Dropzone.js imported into my Angular 2 project via Angular CLI. Though this article was published a little over 2 months ago before this question, I'm noticing this person wasn't use the new Angular CLI syntax with @NgModule.

Is there a way I can import this Dropzone.js npm module into my project?

I've managed to include the Dropzone.js file into my "scripts" property in angular-cli.json here:

"scripts": [
        "../node_modules/dropzone/dist/dropzone.js"
      ],

Here is my dropzone component:

import {
    Component,
    OnInit,
    Input,
    Output,
    EventEmitter,
    ElementRef
} from '@angular/core';
import {
    Http
} from '@angular/http';

@Component({
    selector: 'dropzone',
    templateUrl: './dropzone.component.html',
    styleUrls: ['./dropzone.component.scss']
})
export class DropzoneComponent implements OnInit {

    private _dropzone: Dropzone;

    @Input()
    element: string = ".dropzoneArea";

    @Input()
    url: string = "file/post";

    @Input()
    uploadMultiple: boolean = false;

    @Input()
    maxFileSize: number = 2048;

    @Input()
    clickable: string = ".dropzoneArea";

    @Input()
    autoProcessQueue: boolean = true;

    @Input()
    addRemoveLinks: boolean = false;

    @Input()
    createImageThumbnails: boolean = false;

    @Input()
    previewTemplate: string = "<div style='display:none'></div>";

    @Input()
    acceptedFiles: string = "*";

    @Output()
    sending: EventEmitter < boolean > ;

    @Output()
    uploadprogress: EventEmitter < number > ;

    @Output()
    success: EventEmitter < any > ;

    @Output()
    error: EventEmitter < any > ;

    constructor(private _eleRef: ElementRef, private _http: Http) {

        this.sending = new EventEmitter < boolean > ();
        this.uploadprogress = new EventEmitter < number > ();
        this.success = new EventEmitter < any > ();
        this.error = new EventEmitter < any > ();

    }

    initDropzone() {

        this._http.get("api/getCsrf").subscribe(data => {

            let body = data.json();

            this._dropzone = new Dropzone(this.element, {
                url: this.url,
                uploadMultiple: this.uploadMultiple,
                maxFilesize: this.maxFileSize,
                clickable: this.clickable,
                autoProcessQueue: this.autoProcessQueue,
                addRemoveLinks: this.addRemoveLinks,
                createImageThumbnails: this.createImageThumbnails,
                previewTemplate: this.previewTemplate,
                acceptedFiles: this.acceptedFiles,
                params: {
                    _csrf: body._csrf
                }
            });

            this._dropzone.on("sending", (file, xhr, formaData) => {

                this.sending.emit(true);

            });

            this._dropzone.on("uploadprogress", (file, progress, bytesSent) => {

                this.uploadprogress.emit(progress);

            });

            this._dropzone.on("success", (file) => {

                this.success.emit(file);

            });

            this._dropzone.on("error", (file, message) => {

                this.error.emit(message);

            });

        });

    }

    ngOnInit() {

        this.initDropzone();

    }
}

And here is the error I get when I load my app

client?93b6:76 [default] /projects/project/dropzone/dropzone.component.ts:79:33 
Cannot find name 'Dropzone'.

Anyone have any thoughts on this? I actually can access the Dropzone object, as it's attached to the Window, but I can't get my component to find it.

1条回答
一夜七次
2楼-- · 2020-07-24 06:25

TypeScript doesn't know anything about JS files, so if you have something global you still need to tell TypeScipt about it, one way or another. The easiest way would be to just declare an arbitrary variable

declare var Dropzone: any

This would be enough to compile the code, as TypeScript is simply looking for a name Dropzone. And because we type it to any. it doesn't really care what we do with that symbol afterwards. It just accepts that we know what we're doing with it.

When using JS libraries with TypeScript, it's more preferred to use the TypeScript definition file though. If the library doesn't support TypeScript out the box (doesn't have it's own definition file include in the lib), for popular libraries, there is most likely already a definition file out there. Dropzone is one of those popular libraries.

npm install --save-dev @types/dropzone

Now you can import it wherever you need it

import Dropzone from 'dropzone'

Now you should get strong typing and intellisense. Note that for me, using VSCode, I had to restart the IDE for the intellisense to kick in. This should not be required, it might be a VSCode bug.

查看更多
登录 后发表回答