webpack: Webpack no longer supports define correctly
Do you want to request a feature or report a bug? Bug
What is the current behavior? Webpack no longer appears to support define correctly.
If the current behavior is a bug, please provide the steps to reproduce. We upgraded from webpack 2.2.1 to 2.6.1. In 2.2.1 everything works, but in 2.6.1 it doesn’t.
- Include the
compressjs
module, which uses define like so (see https://github.com/cscott/compressjs/blob/master/main.js)
if (typeof define !== 'function') { var define = require('amdefine')(module); }
define([...], function(...) {
'use strict';
return freeze({
version: "0.0.1",
...
});
});)
- At runtime, you will get an error saying
Uncaught Error: define cannot be used indirect
at e.exports (vendor.ac2023d….js:sourcemap:1)
at Object.<anonymous> (vendor.ac2023d….js:sourcemap:1)
at Object.<anonymous> (vendor.ac2023d….js:sourcemap:1)
at n (commons.1a4acdd….js:sourcemap:1)
at Object.<anonymous> (logos.42ff4f3….js:sourcemap:1)
at Object.<anonymous> (logos.42ff4f3….js:sourcemap:1)
at n (commons.1a4acdd….js:sourcemap:1)
at Object.<anonymous> (logos.42ff4f3….js:sourcemap:1)
at n (commons.1a4acdd….js:sourcemap:1)
at Object.<anonymous> (logos.42ff4f3….js:sourcemap:1)
Attempted workarounds I have tried excluding the module from webpack via noParse (though the docs say not to exclude anything that uses define or require):
module: {
noParse: /(compressjs)/
At runtime, this results in a different error:
main.js:1 Uncaught ReferenceError: require is not defined
at Object.module.exports (main.js:1)
at __webpack_require__ (bootstrap 596e1b2…:54)
at Object.<anonymous> (expander.tsx:61)
at Object.<anonymous> (util.js:57)
at __webpack_require__ (bootstrap 596e1b2…:54)
at Object.<anonymous> (errors.ts:21)
at __webpack_require__ (bootstrap 596e1b2…:54)
at Object.<anonymous> (shortcut-icon.jsx:16)
at __webpack_require__ (bootstrap 596e1b2…:54)
at Object.__webpack_exports__.LogoTabIcon (auth-policy.tenant.client.js:9)
I have tried additionally adding an alias:
resolve: {
alias: {
compressjs: path.join(projectRoot, 'node_modules/compressjs/main.js')
Offending webpack code
It appears the webpack code in Parser.js no longer returns a value for the define expression. In 2.2.1, parser returned a BasicEvaluatedExpression, but as of 2.6.1 it returns nothing, because the “define” definition has been pushed onto the scope for some reason. this.scope.definitions
contains ‘define’ now, whereas it was previously empty.
this.plugin("evaluate Identifier", function(expr) {
const name = this.scope.renames["$" + expr.name] || expr.name;
if(this.scope.definitions.indexOf(expr.name) === -1) { // <-- HERE
const result = this.applyPluginsBailResult1("evaluate Identifier " + name, expr);
if(result) return result;
return new BasicEvaluatedExpression().setIdentifier(name).setRange(expr.range);
} else {
return this.applyPluginsBailResult1("evaluate defined Identifier " + name, expr);
}
});
I’m guessing this is due to the prewalking that was introduced starting in 2.4.0 here.
What is the expected behavior? Modules such as this runs without errors.
If this is a feature request, what is motivation or use case for changing the behavior?
Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System. Testing using the latest Chrome version.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 4
- Comments: 16 (12 by maintainers)
Commits related to this issue
- feature(dist): implements a workaround for https://github.com/webpack/webpack/issues/5316 fixes #45 — committed to mscgenjs/mscgenjs-core by sverweij 6 years ago
- feature(dist) workaround for webpack/webpack#5316 so mscgenjs can be used in webpack 2+ environments (#46) fixes #45 — committed to mscgenjs/mscgenjs-core by sverweij 6 years ago
- Add bz2 decompression support with compressjs (#316) We already proved that compressjs works as a bz2 decoder in the rosbag.js tests: https://github.com/cruise-automation/rosbag.js/blob/68526faa242bb... — committed to cruise-automation/webviz by jtbandes 4 years ago
*rips out webpack and switches to browserify
I’ve found the issue. Problem is that
define
is redefined and shadowsglobal.define
. If you replace removevar
in the source, then it works as expected. I’m not sure webpack can do anything about this.tl;dr:
var define
is hoisted and shadowsglobal.define
which breaks the build.@sverweij no, thank you. I was able to create a repro to analyze what was going on 👍
@ooflorent some old libraries can contain this code, it is not always possible to remove it
@evilebottnawi Looking through the issue it looks like a minimal reproduction example is lacking. Would it be helpful if I provided one?