импортированный модуль webpack не является конструктором

Я создал небольшой JS-модуль, который я собираюсь сделать пакетом npm, но пока он находится только на GitHub. Этот модуль написан на ES6 и SCSS и, таким образом, использует webpack и babel для транспиляции.

Чтобы проверить это, я создал отдельный проект с аналогичной настройкой (webpack и babel). После установки моего модуля npm при попытке импортировать его в свой index.js я получаю следующую ошибку в Инструментах разработчика Chrome: (где x - имя моего модуля)

index.js:11 Uncaught TypeError: x__WEBPACK_IMPORTED_MODULE_1___default.a is not a constructor
    at eval (index.js:11)
    at Object../src/index.js (main.js:368)
    at __webpack_require__ (main.js:20)
    at eval (webpack:///multi_(:8081/webpack)-dev-server/client?:2:18)
    at Object.0 (main.js:390)
    at __webpack_require__ (main.js:20)
    at main.js:69
    at main.js:72

Я просмотрел бесчисленное количество ответов и пробовал бесчисленное количество решений, но безрезультатно. Настройка моего модуля выглядит следующим образом.

.babelrc

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["ie >= 11"]
      }
    }]
  ],
  "plugins": [
    "transform-es2015-modules-commonjs",
    "transform-class-properties"
  ]
}

webpack.common.js

const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const cleanWebpackPlugin = require('clean-webpack-plugin')

const baseSCSS = new ExtractTextPlugin('main/_base.css')
const themeSCSS = new ExtractTextPlugin('main/_theme.css')

module.exports = {
  entry: {
    example: [
      path.join(__dirname, 'src', 'example', 'index.js')
    ],
    main: [
      'idempotent-babel-polyfill',
      path.join(__dirname, 'src', 'index.js')
    ]
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: path.join('[name]', 'index.js')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        }
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract(
          {
            fallback: 'style-loader',
            use: ['css-loader', 'sass-loader']
          }
        )
      },
      {
        test: /\_base-scss$/,
        use: baseSCSS.extract(
          {
            fallback: 'style-loader',
            use: ['css-loader', 'sass-loader']
          }
        )
      },
      {
        test: /\_theme-scss$/,
        use: themeSCSS.extract(
          {
            fallback: 'style-loader',
            use: ['css-loader', 'sass-loader']
          }
        )
      }
    ]
  },
  plugins: [
    new cleanWebpackPlugin('dist', {}),
    new ExtractTextPlugin({ filename: path.join('example', 'style.css') }),
    baseSCSS,
    themeSCSS,
    new HtmlWebpackPlugin({
      inject: false,
      hash: true,
      template: path.join(__dirname, 'src', 'example', 'index.html'),
      filename: path.join('example', 'index.html')
    })
  ]
}

webpack.prod.js

const merge = require('webpack-merge')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const webpack = require('webpack')
const common = require('./webpack.common.js')

module.exports = merge(common, {
  plugins: [
    new UglifyJSPlugin({
      sourceMap: true
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    })
  ],
  mode: 'production'
})

package.json

{
  "name": "my-module-name",
  "version": "1.0.0-beta.1",
  "description": "",
  "main": "dist/main/index.js",
  "scripts": {
    "start": "webpack-dev-server --config webpack.dev.js",
    "server": "node src/server",
    "format": "prettier-standard 'src/**/*.js'",
    "lint": "eslint src",
    "build": "webpack --config webpack.prod.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Liran",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-eslint": "^8.2.3",
    "babel-loader": "^7.1.4",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
    "babel-preset-env": "^1.7.0",
    "clean-webpack-plugin": "^0.1.19",
    "css-loader": "^0.28.11",
    "eslint": "^4.19.1",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "html-webpack-plugin": "^3.2.0",
    "idempotent-babel-polyfill": "^0.1.1",
    "node-sass": "^4.9.0",
    "prettier-standard": "^8.0.1",
    "sass-loader": "^7.0.1",
    "style-loader": "^0.21.0",
    "uglifyjs-webpack-plugin": "^1.2.5",
    "webpack": "^4.6.0",
    "webpack-cli": "^2.0.15",
    "webpack-dev-middleware": "^3.1.3",
    "webpack-dev-server": "^3.1.3",
    "webpack-merge": "^4.1.2"
  }
}

Приветствуется любая помощь / указатели. Если вам нужна дополнительная информация, дайте мне знать.


person Liran H    schedule 20.05.2018    source источник
comment
какая цель установлена ​​в вашей libraryTarget в конфигурации вашего веб-пакета?   -  person PlayMa256    schedule 20.05.2018
comment
Привет, @MatheusSilva, у меня нет этого свойства в конфигурации моего веб-пакета. Я добавил всю свою настройку в свой пост для большей ясности.   -  person Liran H    schedule 20.05.2018
comment
Посмотри на это!. webpack.js.org/guides/author-libraries/#expose- the-library   -  person PlayMa256    schedule 20.05.2018
comment
Ничего себе @MatheusSilva, я не могу поверить в это, но после добавления свойств library и libraryTarget мой модуль теперь безупречно работает в моем тестовом проекте! Большое спасибо за этот действительно полезный указатель. Если вы хотите написать короткий ответ с указанием свойств, которые необходимо добавить (library и libraryTarget), и источника (ссылка на веб-пакет), я с радостью выберу его в качестве принятого ответа.   -  person Liran H    schedule 20.05.2018


Ответы (3)


Он не работает, потому что отсутствуют свойства libraryTarget and library. Выполнив этот веб-пакет, узнайте, какой формат модуля вы хотите создать, например: commonjs (module.exports) или es (export).

Я бы сделал что-то вроде:

...
  output: {
    path: path.join(__dirname, 'dist'),
    filename: path.join('[name]', 'index.js'),
    library: "my-library",
    libraryTarget: "umd" // exposes and know when to use module.exports or exports.
  },
...
person PlayMa256    schedule 20.05.2018

Если вы не являетесь автором библиотеки и у вас возникла проблема с использованием другой библиотеки, вы можете увидеть такую ​​ошибку:

TypeError: [LIBRARY_NAME]__WEBPACK_IMPORTED_MODULEimport { Foo } from 'some-library';
_ is not a constructor

Если это так, возможно, вы неправильно импортируете библиотеку в свой код (это может быть проблемой при экспорте по умолчанию). Дважды проверьте документы библиотеки на предмет использования.

Это может быть так же просто, как изменить это:

import Foo from 'some-library/Foo';

к этому:

import { Foo } from 'some-library';
person David Calhoun    schedule 27.03.2020
comment
Он отлично работал при импорте класса Typescript в файл .js. - person Konrad Gałęzowski; 16.04.2020
comment
Не могли бы вы пояснить, в чем разница, когда используются фигурные скобки, а когда они не используются? Спасибо! - person brance; 18.05.2020
comment
@brance Конечно. Первый пример без фигурных скобок называется экспортом по умолчанию, где вся экспортированная библиотека доступна через переменную Foo (например, Foo.doSomething()). Второй пример с фигурными скобками - это шаблон экспорта модулей, в котором модули явно выбираются из библиотеки по частям, что идеально подходит для встряхивания деревьев. Идея состоит в том, что если в библиотеке 100 модулей, а вы хотите использовать только 1, этот шаблон делает это явным, поэтому сборщики модулей знают, что им не нужно вводить остальные 99 модулей, как это было бы с примером экспорта по умолчанию. . - person David Calhoun; 18.05.2020
comment
@DavidCalhoun Большое спасибо за объяснение! - person brance; 18.05.2020

Ср. Ответ Дэвида Калхуна, если вы столкнетесь с этим со сторонней библиотекой, возможно, вы пытаетесь импортировать модуль CommonJS как модуль ECMAScript. Кажется, что обходной путь заключается в использовании require вместо import, например, вместо

import { Foo } from 'bar'

тебе нужно написать

const Foo = require('bar')

(Может быть, есть более элегантный способ справиться с этим, но у меня это сработало.)

person David Moles    schedule 26.07.2021