问题
I am migrating a library from webpack 1 to webpack 4. Which is to be consumed by another application with webpack 3.
My libraries index.js looks like this,
import * as config from './config';
export default class Helper{
constructor(options) {
this.configurePaths({assetPath: options.assetPath || ''});
}
configurePaths(configuration) {
config.assetPath = configuration.assetPath || config.assetPath;
}
...
}
Webpack of the library has:
const path = require('path');
const env = require('yargs').argv.mode;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const JavaScriptObfuscator = require('webpack-obfuscator');
const webpack = require('webpack');
const version = require('./releaseConfig').version;
const libraryName = 'vektor3d';
let optimization = {}
let plugins = [
new webpack.ProvidePlugin({
vektor3d: 'vektor3d'
})
]
let outputFile;
if (env === 'produciton') {
optimization.minimizer = [new UglifyJsPlugin()]
outputFile = libraryName + '-' + version + '.min.js';
plugins.push(new JavaScriptObfuscator({
rotateUnicodeArray: true,
disableConsoleOutput: false
}, []));
} else {
outputFile = libraryName + '.js';
}
module.exports = {
devtool: env === 'development' ? 'source-map' : undefined,
entry: __dirname + '/src/index.js',
output: {
path: __dirname+'/lib',
filename: outputFile,
library: libraryName,
libraryTarget: 'umd',
umdNamedDefine: true,
globalObject: `(typeof self !== 'undefined' ? self : this)`
},
resolve: {
modules: [path.resolve('./src')],
extensions: ['.js']
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
},
optimization: optimization,
plugins: plugins
};
Now I have to include it as global in another repo whose webpack has html-webpack-plugin and looks like this:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
module.exports = {
entry: {
app: './src/index.js',
},
output: {
filename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
plugins: [
new HtmlWebpackPlugin({
title: '*****'
}),
new HtmlWebpackExternalsPlugin({
externals: [{
module: 'helper',
entry: './helper.js',
global: 'helper',
}]
}),
],
...
};
And then you use it in the application as global like this:
/* global helper */
this.helper = new helper({
assetPath: this.assetPath + '/assets/',
});
With webpack 1 helper used to be a function but with webpack 4 now its a esmodule. So new fails saying not a constructor.
I tried,
var helper = require('helper').default;
as suggested by SO answer by Felix King
edit: This part was solved in a better way with libraryExport: 'default'. But the error mentioned below persists.
But then its starts failing inside the library when using config
key: "configurePaths",
value: function configurePaths(configuration) {
_config__WEBPACK_IMPORTED_MODULE_0__["assetPath"] = configuration.assetPath || _config__WEBPACK_IMPORTED_MODULE_0__["assetPath"];
Error:
Cannot set property assetpath of # which has only a getter
Amzingly the same command runs fine when I execute it on console after stopping it on the same line.
What am I missing? I have updated html-webpack-plugin as well to ^3.
Why does my config exposed in a way that it has only getters?
回答1:
I was able to solve this. The problem was not with the webpack config but the way the config had been imported in the helper file. It requires export default or anouther module binder so I had to add it. This is what changed in my config file.
config.js
--
export let assetPath = 'assets3d';
++
export default {
assetPath: 'assets3d'
}
helper.js
--
import * as config from './config';
++
import config from './config';
回答2:
Try this way.
output: {
path: __dirname+'/lib',
filename: outputFile,
library: 'helper', // if you use this way new helper
libraryExport: 'default', // it is important
libraryTarget: 'umd',
umdNamedDefine: true,
},
I export my library in a similar way.
EDIT
I think I've found a solution. UMD does not support ESM, but you can import the library without 'html-webpack-externals-plugin'. I've just tested. First, I exported the library as above.
Then import the library in the project.
import './helper';
new helper ({});
I also prepared an example on github
来源:https://stackoverflow.com/questions/57180417/webpack-4-36-1-not-working-with-html-webpack-externals-plugin