【问题标题】:Can't import/reference third party library in Angular2无法在 Angular2 中导入/引用第三方库
【发布时间】:2017-02-24 04:44:43
【问题描述】:

抱歉,这个问题已经被问过很多次了。在过去的几天里,我做了很多尝试来让它工作,但我觉得我错过了一些微不足道的事情,这使得这变得不可能。

背景: 使用 .NET Core 作为 Angular2 前端和 webpack 2.2.1 的后端来部署 js/css。 (顺便说一句,我正在使用以下模板,http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/

我正在尝试使用以下内容将 alertifyjs 引用到打字稿服务 (notifications.service.ts) 中:

import { Injectable } from '@angular/core';
//import * as alertify from 'alertifyjs';

declare var alertify: any;
//var alertify = require('alertify.js');

@Injectable()
export class NotificationService {
    private _notifier: any = alertify;
    constructor() {
    }

所以我目前的问题是我该怎么做:

  1. 检查 alertifyjs 是否真的通过 webpack 正确呈现(我尝试通过开发人员工具的控制台调用 alertify,但没有成功)-这不是必需的,但它很好的学习

  2. 让 alertify 通过 webpack 正常工作

  3. 在 Angular2 中引用和使用 alertify

提前感谢您的任何帮助,如果在 StackOverflow 上的某个地方得到了回答,我非常抱歉,我错过了!

另外,我的 webpack 配置如下:

var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin('vendor.css');

module.exports = {
    resolve: {
        extensions: [ '', '.js' ]
    },
    resolveLoader: {
        debug: true,
    },
    module: {
        loaders: [
            { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' },
            { test: /\.css(\?|$)/, loader: extractCSS.extract(['css']) }
        ]
    },
    entry: {
        vendor: [
            '@angular/common',
            '@angular/compiler',
            '@angular/core',
            '@angular/http',
            '@angular/platform-browser',
            '@angular/platform-browser-dynamic',
            '@angular/router',
            '@angular/platform-server',
            'angular2-universal',
            'angular2-universal-polyfills',
            'bootstrap',
            'bootstrap/dist/css/bootstrap.css',
            'es6-shim',
            'es6-promise',
            'jquery',
            'zone.js',
            'alertifyjs',
            //'systemjs',
            'font-awesome/css/font-awesome.css'
        ]
    },
    output: {
        path: path.join(__dirname, 'wwwroot', 'dist'),
        filename: '[name].js',
        library: '[name]_[hash]',
    },
    plugins: [
        extractCSS,
        new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', alertify: 'alertifyjs' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.DllPlugin({
            path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
            name: '[name]_[hash]'
        })
    ].concat(isDevBuild ? [ ] : [
        new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } })
    ])
};

【问题讨论】:

    标签: c# angular typescript webpack asp.net-core


    【解决方案1】:

    您评论的 import/requires 与您的 Webpack 配置不同步,原因之一是。这可能是问题,也可能不是问题,但它会引起麻烦。

    我们来看看

    // fine if 'alertifyjs' is the name of the package
    import * as alertify from 'alertifyjs';
    

    然后我们看到这个

    declare var alertify: any;
    

    这表明你想要全局,一个非常不同的东西,因为你依赖 Webpack 来提供它,除非 alertifyjs 总是创建一个全局,否则这将不起作用,这将是可怕的! 幸运的是,我们看到它不会创建全局,除非没有可用的加载器https://github.com/MohammadYounes/AlertifyJS/blob/master/build/alertify.js#L3571

    然后我们看到了。

    var alertify = require('alertify.js');
    

    这很奇怪。首先,这与上面import 语句中使用的模块说明符"alertifyjs" 不一致。最后,在使用 CommonJS 样式在 TypeScript 中导入 CommonJS 依赖项时,不要使用 varlet 甚至 const,使用 import。也就是说应该避免这种风格。

    现在转到我们的 Webpack 配置

    我们在entry下看到

    vendor: [
        .....
        'alertifyjs',
        .....
    ]
    

    还有一个问题是包的名称是什么? 'alertify.js''alterfyjs'

    但是从这里开始我们会遇到更深的麻烦 继续我们看到的 Webpack 配置

    new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', alertify: 'alertifyjs' }),
    // Maps these identifiers to the jQuery package
    // (because Bootstrap expects it to be a global variable)
    

    那么我们怎么称呼它,它是模块还是全局?

    我们必须做出决定。

    让我们删除所有与 alertify 相关的 Webpack 配置: 从

    中删除它
    entry.vendor
    

    删除

    webpack.ProvidePlugin({ ... })
    

    现在让我们清理 TypeScript

    删除

    declare var alertify: any;
    

    添加

    import * as AlertifyJS from 'alertifyjs';
    

    为什么?因为它将安装在该包名称下的节点模块文件夹中,并且因为在名为 AlertifyJS 而不是 alertify

    的库之后命名导入是一种很好的做法>

    最后,我们会解决这个问题

    @Injectable()
    export class NotificationService {
        private _notifier: any = alertify;
        .....
    }
    

    因为它是坏代码并用这个替换它

    @Injectable()
    export class NotificationService {
        // :any in an assignment context is perhaps the worst TypeScript code we could write.
        notifier = AlertifyJS;
        .....
    }
    

    【讨论】:

    • 哇,感谢您的全面回答,我现在就试一试
    • 该死的,你是上帝派来的。付出了巨大的努力才能让它发挥作用,而你却完美地击中了它。
    • 很高兴能提供帮助:)
    猜你喜欢
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多