如何在Angular 4项目中导入bootstrap-daterangepicker?

时间:2017-10-11 01:27:28

标签: javascript angular typescript webpack angular-cli

我尝试按照 this 教程中的说明在我的Angular 4项目中集成bootstrap-daterangepicker,但是我收到以下错误和警告。错误行是:Uncaught TypeError: __webpack_require__.i(...) is not a function。有谁知道如何解决这个问题?

enter image description here

1 个答案:

答案 0 :(得分:1)

问题是该教程使用了无效的ESM - > CommonJS互操作。请改用import $ from jQuery;。调用名称空间导入(* as)在ECMAScript中无效。

TLDR:

import $ from 'jquery';
import 'bootstrap-daterangepicker';

并在--allowSyntheticDefaultImports中设置"allowSyntheticDefaultImports": true"compilerOptions"),以便TypeScript使用合成的默认导入来正确检查代码。

我还在文章中添加了a comment to that effect

<强>详细信息:

基本上,ECMASCript规范禁止将Module Namespace Objects作为函数调用。当您使用语法

import * as imported from 'some-module';

创建名为imported的模块命名空间对象。此对象公开指定模块的每个导出以进行限定访问,例如imported.aa导出'some-module'。但是,在仅导出单个值的AMD或CommonJS模块中,通常将此值导出为模块本身。这通常写为

// AMD
define(function () {
  const $ = {...}; // jquery implementation

  return $;
});

或者

// CommonJS
const $ = {...}; // jquery implementation

module.exports = $;

define返回的值或分配给module.exports的值代表模块本身。

要导入此类导出,通常会编写

// AMD
define(["jquery"], function ($) {
  $('div').text('set via jQuery');
});

或者

// CommonJS
const $ = requere("jquery");
$('div').text('set via jQuery');

将其与通常写为

的命名导出进行比较
// AMD
define(function () {
  const $ = {...}; // jquery implementation

  return {$};
});

或者

// CommonJS
const $ = {...}; // jquery implementation

module.exports.$ = $;

要导入此类导出,通常会编写

// AMD
define(["jquery"], function ($) {
  $.$('div').text('set via jQuery');
});

或者

// CommonJS
const $ = require("jquery");
$.$('div').text('set via jQuery');

现在回到ES模块世界,* as语法将指定的导出绑定聚合到一个对象中,用于点(.)访问。

与AMD和CommonJS模块形成鲜明对比的是,在ES模块中,导出的所有内容都必须以名称导出。

但是,ES模块中仍然通过default导出/导入语法和语义提供了导出和导入表示模块本身的单个值的实用性和简单性。那个语法是

// ESM
const something = {...};
export default $;

通常以

消费
// ESM
import $ from 'some-module';

这在概念上类似于分配给module.exports或从define返回单个值,但实际上,default不是匿名的,它是名为的导出 default

所以问题就变成了,当我们有一个AMD或CommonJS模块将值导出为模块本身时(通常使用上述模式之一),我们如何将它导入ES模块?我们无法使用require。我们不能导入没有名字的东西。好的互操作,虽然有点不稳定,但是module.exports的值或define返回的值可用作default导出。这带来了许多问题,但它允许我们写

import $ from 'jquery';

这是可行的,因为default只是一个名为default的导出。无法调用命名空间。

不幸的是,由于ES模块规范的波动,每个指定的互操作机制的不确定性,并且由于各种历史原因,TypeScript历史上已经出现了不同的溃败,

import * as imported from 'some-module';

暗示

const imported = require('some-module');

type 级别。此外,它自动提供导出为AMD和CommonJS模块的值为default,这意味着正确的语法可能在运行时失败。

但是,TypeScript 将解决此问题。

与此同时,如果您使用模块互操作感知工具(如SystemJS或Webpack 3),则可以正确编写

import imported from 'some-module';

今天在TypeScript中。 指定--allowSyntheticDefaultImports编译器选项,以针对AMD或CommonJS模块启用此语法的正确类型检查。