webpack imported module is not a constructor

2020-06-08 14:49发布

I created a small JS module which I intend to make an npm package, but for now is just on GitHub. This module is written in ES6 and SCSS, and is thus relying on webpack and babel for transpilation.

To test it, I created a separate project with a similar setup (webpack and babel). After npm installing my module, when trying to import it into my index.js, I get the following error in Chrome Developer Tools: (with x being my module's name)

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

I've looked through countless answers and tried countless solutions, to no avail. My module's setup is as follows.

.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"
  }
}

Any help/pointers would be greatly appreciated. If you need more information, please let me know.

2条回答
该账号已被封号
2楼-- · 2020-06-08 15:15

If you are not the library author and are having a problem consuming another library, you may be seeing an error like this:

TypeError: [LIBRARY_NAME]__WEBPACK_IMPORTED_MODULE_3__ is not a constructor

If that's the case, you may be importing the library incorrectly in your code (it may be a problem with default exports). Double check the library docs for usage.

It may be as simple as changing this:

import Foo from 'some-library/Foo';

to this:

import { Foo } from 'some-library';
查看更多
Animai°情兽
3楼-- · 2020-06-08 15:31

It is not working because it is missing libraryTarget and library properties. By doing that webpack know which format of module you would like to create, i.e: commonjs (module.exports) or es (export).

I would do something like:

...
  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.
  },
...
查看更多
登录 后发表回答