Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack no longer supports define correctly #5316

Closed
davidschwegler opened this issue Jul 18, 2017 · 16 comments

Comments

Projects
None yet
7 participants
@davidschwegler
Copy link

commented Jul 18, 2017

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.

@davidschwegler davidschwegler changed the title Webpack no longer appears to support define correctly Webpack no longer supports define correctly Jul 18, 2017

@sokra

This comment has been minimized.

Copy link
Member

commented Jul 19, 2017

yep this is a problem...

@sokra sokra modified the milestone: webpack 3 Jul 21, 2017

sverweij added a commit to mscgenjs/mscgenjs-core that referenced this issue Jan 3, 2018

sverweij added a commit to mscgenjs/mscgenjs-core that referenced this issue Jan 5, 2018

feature(dist) workaround for webpack/webpack#5316 so mscgenjs can be …
…used in webpack 2+ environments (#46)

fixes #45
@evilebottnawi

This comment has been minimized.

Copy link
Member

commented May 6, 2018

/cc @davidschwegler problem still exists in webpack@4?

@sverweij

This comment has been minimized.

Copy link

commented May 21, 2018

Hi @evilebottnawi I've retried today using webpack 4.8.3 and can confirm the issue with requirejs/ amdefine still exists.

@sverweij

This comment has been minimized.

Copy link

commented May 22, 2018

@evilebottnawi Looking through the issue it looks like a minimal reproduction example is lacking. Would it be helpful if I provided one?

@hayesmaker

This comment has been minimized.

Copy link

commented Jun 8, 2018

*rips out webpack and switches to browserify

@evilebottnawi

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@ooflorent ooflorent self-assigned this Jun 8, 2018

@ooflorent

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@sverweij Absolutely. Any simple repro would be appreciated.

@ooflorent

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

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.

@evilebottnawi

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@ooflorent some old libraries can contain this code, it is not always possible to remove it

@ooflorent

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@evilebottnawi I understand but this is not a webpack bug. webpack fixed a bug that broke existing libraries because they were doing broken things.

@ooflorent

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

A fix would be to ignore the redefinition of define but that would break code that requires define to be shadowed.

@evilebottnawi

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@ooflorent looks like we can close issue here, but @sokra add bug labels, maybe he have idea how solve this without break code

@sverweij

This comment has been minimized.

Copy link

commented Jun 8, 2018

If this cannot be solved without breaking (t.b.c.) it might be useful to document any known workarounds for anyone bumping into this (I can help).

@ooflorent seeing you found the root cause: still interested in a simple repro?

@ooflorent

This comment has been minimized.

Copy link
Member

commented Jun 8, 2018

@sverweij no, thank you. I was able to create a repro to analyze what was going on 👍

@webpack-bot

This comment has been minimized.

Copy link
Contributor

commented Dec 8, 2018

This issue had no activity for at least half a year.

It's subject to automatic issue closing if there is no activity in the next 15 days.

@webpack-bot webpack-bot added the inactive label Dec 8, 2018

@webpack-bot

This comment has been minimized.

Copy link
Contributor

commented Dec 23, 2018

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.