webpack imported module is not a constructor

谁说胖子不能爱 提交于 2019-12-09 16:17:46

问题


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.


回答1:


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


来源:https://stackoverflow.com/questions/50435253/webpack-imported-module-is-not-a-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!