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

Ability to ignore modules at least in well-known environments #474

Closed
gimenete opened this issue Jan 2, 2018 · 11 comments
Closed

Ability to ignore modules at least in well-known environments #474

gimenete opened this issue Jan 2, 2018 · 11 comments

Comments

@gimenete
Copy link

gimenete commented Jan 2, 2018

This is a 🙋 feature request.

I was trying to use parcel.js for an electron application. The goal is to have a lightweight HMR solution without the need to set up something complex. Besides I love the fine grained control you can get with module.hot.dispose and module.hot.accept.

parcel index.html

🤔 Expected Behavior

parcel.js should not bundle the electron package.

😯 Current Behavior

🚨  /Users/gimenete/projects/unicycle/unicycle/node_modules/electron/index.js: Could not statically evaluate fs call

Basically parcel is trying to bundle the electron package itself. Internally electron does things with the file system. I cannot control that, but even more: there's no need to bundle electron itself with the code.

💁 Possible Solution

I like the idea of having well-known environment configurations, such as eslint does. So we could have:

parcel --env electron index.html

This would apply some additional rules to parcel due to the selected environment. For example ignoring electron or even ignoring all node_modules.

💻 Code Sample

As soon as you import electron itself:

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>
  <script>
    window.nodeRequire = require;
    delete window.require;
    delete window.exports;
    delete window.module;
  </script>
  <script src="./hello.js"></script>
</body>

</html>
// hello.js
import * as electron from "electron";

console.log('hello world');

The build fails. The additional <script> with those deletes is due to this: #321 Which is another thing the --env idea could fix.

🌍 Your Environment

Software Version(s)
Parcel 1.4.1
Node v8.9.1
npm/Yarn npm 5.5.1
Operating System macOS High Sierra
@gimenete
Copy link
Author

gimenete commented Jan 3, 2018

I've created a repo to reproduce the problem: https://github.com/gimenete/electron-parcel-bug-report

@bardiarastin
Copy link

any news on this ? unable to use parcel in electron environments :(

@astra137
Copy link

I toyed around with this by skipping in dependencies.js anything that looked like packages. I'm guessing Parcel's previous require stuff would get stuff loaded, but I'm still studying how things get added to bundles. I'm going to keep throwing myself at it for a bit.

@morajabi
Copy link

I'm using it in an Electron app, can anyone guide me either how to fix this in a PR or suggest a workaround? I'd happily do a PR.

@morajabi
Copy link

morajabi commented Jan 26, 2018

OK, it seems a workaround can be something like this, so Parcel won't bundle it.

<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script>
    window.nodeRequire = require;
    delete window.require;
    delete window.exports;
    delete window.module;
    const electron = nodeRequire('electron');
  </script>
</head>

<body>
  <div id="root"></div>
  <script src="./index.js"></script>
</body>

</html>

Or another solution is, if you need it in the renderer js entry file (which is bundled with Parcel), you can require it like this:

// renderer.js
const electron = eval(`require('electron')`) /* or nodeRequire if you changed it */

By using eval parcel won't bundle this, but in the runtime, it'll be loaded normally.

@astra137
Copy link

astra137 commented Jan 26, 2018

Per the guidance of @devongovett in #448, I added a simple and dumb check to Resolver.js to return null if the filename started with . or / and it worked. I had to add some null handlers in Bundler.js, but it was working for my Vue powered Electron app.

However, because require exists while the bundle is loading, it is saved at module.bundle.parent and exposed that way to the HMR module. Plugins can override the builtins, like parcel-plugin-vue does, which ensures that the check for parent happens. Hot loading cannot be enabled without also sending a pull request off to each plugin that happens to override the altered HMR builtin.

I don't know if I have exhausted all of the options, but I think parcel would need to disallow plugins from altering built-in packagers for this feature to be stable.

@morajabi
Copy link

@maccelerated I think the solution above I posted is simpler, no?

@astra137
Copy link

I was trying to prevent Parcel from bundling any package, but yeah, escaping electron like that would get you up and running.

@gimenete
Copy link
Author

escaping electron like that should be only a quick workaround. But doesn't work in all scenarios. For example if you are transpiling from typescript, you don't have much control over how typescript generates the require() calls.

@astra137
Copy link

Just throwing a reference in to #192 node bundling mode and its PR #652, which seems to be a HMR-less solution.

@lbguilherme
Copy link
Contributor

@maccelerated and others: modified PR #652 for electron support. Please check if it's ok for your usecase.

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

No branches or pull requests

6 participants