简体   繁体   中英

How to import bootstrap-daterangepicker in Angular 4 project?

I tried following instructions from this tutorial to integrate bootstrap-daterangepicker in my Angular 4 project but I get the following error and warning. The error line is: Uncaught TypeError: __webpack_require__.i(...) is not a function . Would anyone know how to fix this?

在此处输入图片说明

The problem is that the tutorial uses invalid ESM -> CommonJS interop. Use import $ from jQuery; instead. Calling a namespace import ( * as ) is invalid in ECMAScript.

TLDR: write

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

and set --allowSyntheticDefaultImports ( "allowSyntheticDefaultImports": true in "compilerOptions" ) so that TypeScript typechecks code using the synthesized default import correctly.

I added a comment to that effect to the article as well.

Details:

Basically, the ECMASCript specification forbids calling Module Namespace Objects as functions. When you use the syntax

import * as imported from 'some-module';

A module namespace object named imported is created. This objects exposes each export of the specified module for qualified access such as imported.a where a is exported by 'some-module' . However, in an AMD or CommonJS module that only exports a single value it is common to export this value as the module itself. This is typically written as

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

  return $;
});

Or

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

module.exports = $;

The value returned by define or the value assigned to module.exports represent the module itself.

To import such an export one would typically write

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

Or

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

Compare that to a named export typically written as

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

  return {$};
});

Or

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

module.exports.$ = $;

To import such an export one would typically write

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

Or

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

Now back in the ES Module world, the * as syntax aggregates the named exported bindings into an object for dotted ( . ) access.

In sharp contrast to AMD and CommonJS modules, in an ES Module everything exported must exported under a name .

However, the utility and simplicity of exporting and importing a single value representing the module itself is still provided for in ES Modules by way of the default export/import syntax and semantics. That syntax is

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

And is typically consumed as

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

This is conceptually similar to assigning to module.exports or returning a single value from define but in actuality, default is not anonymous it is an export named default .

So the question becomes, when we have an AMD or CommonJS module that exports a value as the module itself (usually using one of the patterns described above), how do we import it into an ES Module? require is not available to us. We cannot import something without a name. Well interop, while somewhat in flux is to make the value of module.exports or that returned by define available as the default export. This poses a number of problems but it allows us to write

import $ from 'jquery';

This is viable because default which is just an export named default can be called. A namespace cannot be called.

Unfortunately, due to fluctuations in the ES Module spec, the uncertainty of an interop mechanism every being specified, and for various historical reasons, TypeScript has historically gone a different rout, taking

import * as imported from 'some-module';

to imply

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

At the type level. Furthermore, it does not yet automatically provide values exported as AMD and CommonJS Modules as the default which means that the correct syntax can fail at runtime.

However, TypeScript is going to address this.

In the meantime, if you use a module interop aware tool such as SystemJS or Webpack 3, you can correctly write

import imported from 'some-module';

today in TypeScript. Specify the --allowSyntheticDefaultImports compiler option to enable proper typechecking of this syntax against AMD or CommonJS modules.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM