Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

output iife without name #274

Closed
zanona opened this issue Jan 3, 2018 · 10 comments
Closed

output iife without name #274

zanona opened this issue Jan 3, 2018 · 10 comments

Comments

@zanona
Copy link

zanona commented Jan 3, 2018

Case A

rollup a-import.js -c --output.format iife --output.name myBundle

a-import.js

import b from './b';
console.log(b.foo);

result 馃憣 this is what I would expect

(function () {
'use strict';
var b = { foo: 'bar' };
console.log(b.foo);
}());

However, when using a-require.js instead, where require is used instead of import the result is:

Case B

rollup a-require.js -c --output.format iife --output.name myBundle

a-require.js

const b = require('./b');
console.log(b.foo);

result 馃槙 not quite what I expect

var myBundle = (function () { //<-- why do I need a named export?
'use strict';
var b = { foo: 'bar' };
console.log(b.foo);
var a = {}; // <-- why is it creating a module out of the entry file since nothing is being exported?
return a;
}());

How can I get the same output of case A when using commonjs require instead?

  • Just highlighting that --output.name is necessary on case B otherwise the command will fail with [!] Error: You must supply options.name for IIFE bundles

For reference, here are the involved files

rollup.config.js

import commonjs from 'rollup-plugin-commonjs';
export default { plugins: [commonjs()] };

b.js

module.exports = { foo: 'bar' };
@paulocoghi
Copy link

paulocoghi commented May 14, 2018

Is there any way to do this (output an iife without name)?

I am also in a situation that this would be better.

@noahbrenner
Copy link

I'd also like this. The current behavior actually changes the functioning of the input code. In the OP's example, there is no object created or returned, so doing so in the output is not expected behavior and does not align with how ES modules are processed by rollup.

I could understand requiring an export in cjs format, but an IIFE frequently stands alone and doesn't need to affect the outer namespace.

@mcshaman
Copy link

I too would like this... I have been trying to work out for hours now why IIFEs work differently between import and require statements. My entry point script uses CommonJS require statements and is run by the browser on load. The IIFE is just to create scope... it doesn't need to return a value.

@LeeeeeeM
Copy link

rollup/rollup#2586
same question

@bterrier
Copy link

Any news on this ?

In my case the script is injected into an interpreter (e.g. node bundle.js).
If the iife has no name the result of the script is the returned value from the iife.
With the var name = (...);, the return of the script is undefined...

Note that when the "input" module has no export default, the iife has no return statement and rollup does not complain about the iife not having a name.

@eight04
Copy link

eight04 commented Oct 21, 2019

A workaround is to use an ES module as the entry point so it won't be modified by the plugin, or you can try cjs-es plugin.

@bterrier
Copy link

I am using es2015 modules (at least I should since the JS in generated by tsc with the es2015 module option).

The thing is I do need to have an IIFE with all the dependencies inlined inside the IIFE.
The only thing that does not work for me is that var name =.

So to solve this, either I have to remove the var name = or wrap the bundle into another IIFE. Which seems a bit silly.

@lukastaegert
Copy link
Member

lukastaegert commented Oct 23, 2019

Copied from my comment in rollup/rollup#3181:

Instead of trying to fix in Rollup what is not really broken (the things is: All CJS files DO have a default export which is an empty object if nobody messes with exports or module.exports), I would very much recommend the solution that @eight04 mentioned:

Basically you create a new entry point for your code that contains nothing but an import of your old entry point without any bindings, and bundle that one:

// a-require.js: this is the old entry
const b = require('./b');
console.log(b.foo);

// b.js
module.exports = {foo: 'bar'};

// entry.js: this is the new entry
import './a-require';

Now if you bundle entry.js (and do not forget the commonjs plugin), you will get this output:

(function () {
	'use strict';

	var b = {foo: 'bar'};

	console.log(b.foo);

}());

This will work, no matter if your original entry point is CJS or ESM. In case your original entry points DOES have exports, this has an additional advantage, as tree-shaking will try to remove all code that does not have observable side-effects such as calling or modifying global variables, so you will get a smaller bundle.

@lukastaegert
Copy link
Member

To make it clear, as there seems to be a lot of confusion in this thread: The main problem is that the entry point is commonjs. Now there may be reasons for doing this, but if you can avoid it, you should use ES modules, i.e. import and export, but not require and exports.

IF you a re writing a CJS module, then rollup-plugin-commonjs tries to be as spec compliant as it can by creating a default export with an empty object. Because if there was another module importing this module, this is what it would get even if there are no "explicit" exports. Yes, this is how CommonJS was made. And the plugin does not know if there is another module in the graph importing it, so it must include the export to be safe.

So there is no pure CJS solution here, but it can be easily side-stepped by adding a wrapping ESM entry.

@shellscape
Copy link
Contributor

Hey folks (this is a canned reply, but we mean it!). Thanks to everyone who participated in this issue. We're getting ready to move this plugin to a new home at https://github.com/rollup/plugins, and we have to do some spring cleaning of the issues to make that happen. We're going to close this one, but it doesn't mean that it's not still valid. We've got some time yet before the move while we resolve pending Pull Requests, so if this issue is still relevant, please @ me and I'll make sure it gets transferred to the new repo. 馃嵑

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants