GithubHelp home page GithubHelp logo

florianrappl / parcel-plugin-externals Goto Github PK

View Code? Open in Web Editor NEW
47.0 3.0 3.0 52 KB

Parcel plugin for declaring externals. These externals will not be bundled. :package:

Home Page: https://piral.io

License: MIT License

JavaScript 100.00%
parcel parcel-bundler parcel-plugin bundle externals dependencies

parcel-plugin-externals's Issues

Use @parcel/logger instead of console

As I use in my own plugin, there is a package @parcel/logger that integrates directly with Parcel's logging system. I would suggest using it instead of console because it looks much cleaner (you can install that plugin to see for yourself). You could also throw errors for prettier output than console.error.

I have a declaration file for @parcel/logger, which should give you a general sense of its API.

Exception on browser property set to false

The package.json browser field allows properties to be set to false to exclude files from bundling. However, this causes parcel-plugin-externals to crash as resolve does not accept values other than strings.

How to alias React and ReactDOM as `wp.element`?

Continuing from parcel-bundler/parcel#144 (comment)

Maybe I'm not doing it just right or not understanding how things work, but here's what I've got so far:

The issue here is that WordPress is already loading React and ReactDOM via the @wordpress/element package from yoursite-com/wp-includes/js/dist/element.js (WordPress core, not my own path, as you can see).

Here's my package.json:

{
	...
	"dependencies": {
		"react-notifications-component": "^2.3.0"
	},
	"devDependencies": {
		"@babel/core": "^7.8.7",
		"@wordpress/scripts": "^7.1.2",
		"npm-run-all": "^4.1.5",
		"parcel-bundler": "^1.12.4",
		"parcel-plugin-externals": "^0.3.3",
		"postcss-modules": "^1.5.0"
	},
	"babel": {
		"presets": [
			"@wordpress/default"
		]
	},
	"browserslist": [
		"extends @wordpress/browserslist-config"
	],
	"externals": "./.externals.js"
}

Here's the .externals.js that my package.json runs:

const rxWp = /node_modules\/@wordpress\/(.*?)\//;
const rxBabel = /node_modules\/@babel\/(.*?)\//;
const rxReact = /node_modules\/react-(.*?)\//;

module.exports = function( path ) {
	const wp = rxWp.exec( path );
	const babel = rxBabel.exec( path );
	const react = rxReact.exec( path );

	let wpSuffix;

	let babelSuffix;

	let reactSuffix;
	let reactName;

	if ( wp ) {
		wpSuffix = wp[ 1 ];
		return `@wordpress/${wpSuffix} => require('@wordpress/${wpSuffix}')`;
	}

	if ( react ) {
		reactSuffix = react[ 1 ];
		reactName = reactSuffix[ 0 ].toUpperCase() + reactSuffix.substr( 1 );
		return `react-${reactSuffix} => React${reactName}`;
	}

	if ( babel ) {
		babelSuffix = babel[ 1 ];
		return `@babel/${babelSuffix} => require('@babel/${babelSuffix}')`;
	}

	return undefined;
};

HTML Externals

Just a quick thought, since I'm using the externals key in parcel-plugin-html-externals as well, that might introduce conflicts in case someone wanted to use both packages. Would you be interested in merging or introducing HTML support here?

Bundling fails when [email protected] is added to external

When adding [email protected] to externals bundling is failing due to the specified module doesn't exist.

ร— ENOENT: no such file or directory, lstat 'C:\Users<...>\node_modules\react-dom\unstable-fizz.browser.js'
at realpathSync (fs.js:1476:7)
at externals.push.modules.map (C:\Users<...>\node_modules\parcel-plugin-externals\utils.js:165:15)
at Array.map ()
at makeResolver (C:\Users<...>\node_modules\parcel-plugin-externals\utils.js:163:18)
at combineExternalsPrimitive (C:\Users<...>\node_modules\parcel-plugin-externals\utils.js:201:12)
at combineExternals (C:\Users<...>\node_modules\parcel-plugin-externals\utils.js:210:18)
at retrieveExternals (C:\Users<...>\node_modules\parcel-plugin-externals\utils.js:257:14)
at module.exports (C:\Users<...>\node_modules\parcel-plugin-externals\index.js:9:21)
at Bundler.loadPlugins (C:\Users<...>\node_modules\parcel\src\Bundler.js:219:17)

In package.json of react-dom:

"browser": {
"./server.js": "./server.browser.js",
"./unstable-fizz.js": "./unstable-fizz.browser.js"
},

In such cases i.e. when referenced module doesn't exist makeResolver function breaks.

External syntax

Any reason the externals value has custom syntax with '=>' instead of an object? Would prefer something like this

{
  "externals": {
    "react": "React"
  }
}

over

{
  "externals": [
    "react => React"
  ]
}

Ignores hoisted modules

Hi!

I am happy user of your plugin. However I am trying to move a site using it to a package inside a monorepo that uses lerna + yarn workspaces.

With this setup all the dependencies are hoisted. This means the paths passded by parcel will be different from the ones calculated by this plugin and the external modules will not be externalized.

I've created a sample repo where you can see the issue in action: https://github.com/4lejandrito/parcel-plugin-externals-yarn-workspaces-issue-demo.

Run yarn && yarn start on it and you'll get a page that should have a dependency externalized (and therefore fail) but it will actually exist in the bundle and print a message on the screen.

Question: Is there a way to set all modules to be externals?

I am currently working with webpack and considering looking into adoption of parcel for a variety of reasons. So far, externals seems to be the primary feature that is missing when considering this adoption. We need to leverage externals in two different ways. I wanted to know if this plugin currently supports our two use cases and, if not, whether it would be possible to add this support.

First use case: typical webpack externals. This is the normal use case and the one I am fairly certain is supported. In a situation where I am developing a single page application and I know that jQuery will be available globally I can list it as an external and not include it in the application's bundle.

Second use case: marking all node_modules as externals. This is the use case I am not as confident is supported. We develop a number of internal libraries and we know for a fact that the dependencies of those libraries will be downloaded by the applications that consume those libraries. Therefore, whenever we bundle a library, we list all of its dependencies as externals using a library designed for webpack - webpack-node-externals. Is it possible to mimic this behavior using this plugin?

(Node 8.16.x) SyntaxError: Unexpected token { ...

I'm seeing this error in version 0.4.1 and node 8.16.x:

  Plugin parcel-plugin-externals failed to initialize: /foo/node_modules/parcel-plugin-externals/utils.js:137
  } catch {
          ^

SyntaxError: Unexpected token {
    at NativeCompileCache._moduleCompile (/foo/node_modules/v8-compile-cache/v8-compile-cache.js:242:18)
    at Module._compile (/foo/node_modules/v8-compile-cache/v8-compile-cache.js:186:36)
...

Looks like that should be catch () {.... Works in Node 10.16.x.

Parcel v2

Is this plugin compatible with Parcel v2 beta?

I tried every combination of:

{
	"peerDependencies": {
		"jquery": "*",
		"jquery.js": "*",
		"bootstrap": "*"
	},
	"externals": [
		"jquery => jQuery",
		"jQuery => jquery",
		"jquery => require('jquery')",
		"jQuery => require('jquery')",
		"jQuery => require('node_modules/jquery/dist/jquery.js')",
		"jquery => require('node_modules/jquery/dist/jquery.js')",
		"$ => require('node_modules/jquery/dist/jquery.js')"
	],
}

Importing like that:

import $ from 'jquery';

But jQuery is bundled into my app.js whatsoever :-(

Help how to 'externalize' all of WordPress' globals

2 questions for a situation where my app loads within WordPress and therefore globals like jQuery, Moment, Lodash, React, and ReactDOM are already...

References:

  1. What does "*" actually do?
  2. Why doesn't lodash.isequal get excluded from my own build?

Any and all suggestions for my "externals" are welcome! :D

===

Here's a Parcel build report:

image

Here's an example npm ls ...:

image

Here's my externals:

{
...
"externals": {
	"@babel/runtime/regenerator": "regeneratorRuntime",
	"@wordpress/element": "wp.element",
	"jquery": "jQuery",
	"lodash": "lodash",
	"lodash-es": "lodash",
	"moment": "*",
	"react": "React",
	"react-dom": "ReactDOM"
}
...
}

Broken output with "--bundle-node-modules" option

Env:

"dependencies": {
  "aws-sdk": "2.585.0"
},
"externals": {
  "aws-sdk": "aws-sdk"
},
"devDependencies": {
  "@types/aws-lambda": "^8.10.47",
  "@types/node": "^13.9.8",
  "parcel-bundler": "^1.12.4",
  "parcel-plugin-externals": "^0.3.3-pre.20200323.2",
  "typescript": "^3.8.3"
},
"engines": {
  "node": ">=12.0.0 <13.0.0"
}

Code written in Typescript.

What I wanted to achieve:

Generally bundle all node_modules except a few external ones ("aws-sdk" for a lambda in my case).

Problem I encountered:

My index.ts looks something like this:

import { Handler } from 'aws-lambda'; // Types only "@types/aws-lambda" in devDependencies
import { Athena } from 'aws-sdk';
import { format } from 'util';
// Other code imports local to src folder [...]

export const handler: Handler = async (event, context) => {
  const athenaService = new Athena();

  //...

  return format('%s Done', 'Really');
};

When I compile this normally with e.g.
parcel build ./src/index.ts --out-dir dist --out-file index.js --global handler --target=node --experimental-scope-hoisting --no-source-maps --no-content-hash
it works correctly and the require('aws-sdk') is correctly left in the output.

But if I compile it with the --bundle-node-modules it breaks and the output contains something like this:

var k={};k=aws-sdk;

also the parcel output shows:

dist/index.js                                1.33 KB    1.38s
dist/aws-sdk => aws-sdk.5848e953.external        0 B     26ms

In both cases the require('util') is present in the output as it should.

How use parcel-plugin-externals properly in development/production mode ?

When I run the script:

  • " parcel build src/index.html " to build on production, the externals ones are not bundled. Good.

  • "parcel src/index.html" to develop, the external ones are NOT bundled but I need them in dev mode. ๐Ÿ˜ฅ

How can I prevent this behavior? I need those modules to develop

I tried to do

NODE_ENV=production
NODE_ENV=development

the externals modules are included in package.json into "externals" array.

Let me know if you need any more details

Thanks

Can't tell if plugin is running

I am using Parcel 1.12.4 which is installed globally.
I installed this plugin globally
npm install -g parcel-plugin-externals

I ran into this error message:
'Error: Cannot find module 'parcel-bundler/src/Logger'

But I think I resolved it by adding some missing files as per
https://stackoverflow.com/questions/62870976/parcel-plugin-transcrypt-fails-with-error-cannot-find-module-parcel-bundler-s

I added the following to my package.json but I am not confident that I did it correctly.

 "externals": [
    "userConfig"
  ],
  "alias": {
    "userConfig": "../config/user_config.js"
  }

When I run my parcel build I can not see if the plugin is working, but my desired end result is definitely not working.

I think I have an incredibly simple use case. I have an external file that I want to import manually and I want Parcel to ignore it. I want my import statement to remain exactly as it is:
At run time if I perform
import('../config/user_config.js')

I want it to read that actual file on in that location and not be redirected to some bundled code.

Am I asking too much?

Support for fake modules?

I am writing a VSCode extension that imports the vscode module for interfaces and other things. However, this module does not exist and is provided on the fly by the editor, so there is an error when trying to build the extension. Does this plugin support scenarios like this?

Here is the project: https://github.com/arnohovhannisyan/vscode-syncify.

I tried adding the vscode module to both externals and peerDependencies but it didn't work.

Uncaught ReferenceError: React is not defined

I'm able to exclude react from the build using "parcel-plugin-externals".

However, when I dynamically load the compiled script file into another project that already is using react, I get the error message "Uncaught ReferenceError: React is not defined". How do I make the script load the excluded module from the script it is being loaded into?

( If that make sense to you, I realize this is a very incomplete description )


More details on what I'm trying to do:

We are building a SPA application for a CMS using react, parcel and typescript.
We want to build a plugin system that will allow third party developers to create their own controls that plug into the CMS UI. These ui components must be loaded dynamically and from external sources.

We distribute our CMS components to NPMJS and third party developers will develop their plugins by referencing the NPM modules. The output of these projects should only contain the custom code they have written. I'm trying to use Parcel with "parcel-plugin-externals" to build a script file that can be loaded dynamically into the CMS at runtime.

To load the script file with:

const loadedScrips: Set<string> = new Set();
async function loadScript(url: string): Promise<void> {
    if (loadedScrips.has(url)) return;
    loadedScrips.add(url);
    return new Promise((resolve, reject) => {
        var script = document.createElement('script');
        script.onload = () => resolve();
        script.onerror = (err) => reject(err);
        script.src = url;
        document.head.appendChild(script);
    });
}

In the package,json we have added:

  "externals": {
    "react": "React"
  },

Without the "externals" it works, with the "externals" section it fails with:
"Uncaught ReferenceError: React is not defined"

If you want, I could make a simplified example and upload it to github.

Any help with the matter is greatly appreciated !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.