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.

  1. 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",
       ...
    });
});)
  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

Most upvoted comments

*rips out webpack and switches to browserify

I’ve found the issue. Problem is that define is redefined and shadows global.define. If you replace remove var 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 shadows global.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?