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

Add support for multiple entry points #1119

Merged
merged 2 commits into from May 1, 2018
Merged

Add support for multiple entry points #1119

merged 2 commits into from May 1, 2018

Conversation

devongovett
Copy link
Member

Closes #189.

This PR adds support for multiple entry points to Parcel. It works by simply adding an additional fake node at the root of the bundle tree and attaching each entry asset to it as a child. If there is only one child, that child bundle is returned as it was before for convenience and to maintain backward compatibility.

Entry points can be passed to parcel as a list of files, or as a glob or list of globs. e.g. parcel *.html will run parcel over all HTML files in the current directory. Common dependencies between the entry points, such as a shared JS file, are deduped and produce a single output file that is linked to by both HTML entry points.

@davidnagli
Copy link
Contributor

Umm doesn’t this break backwards-compatibility for anyone using Parcel programmatically (requiring Parcel and then manually instanciating Bundler)?? 🤔

@devongovett
Copy link
Member Author

Should be backward compatible. It will check if the input is a string rather than an array, and convert it for you.

parcel/src/Bundler.js

Lines 65 to 80 in 81aaf9b

normalizeEntries(entryFiles) {
// Support passing a single file
if (entryFiles && !Array.isArray(entryFiles)) {
entryFiles = [entryFiles];
}
// If no entry files provided, resolve the entry point from the current directory.
if (!entryFiles || entryFiles.length === 0) {
entryFiles = [process.cwd()];
}
// Match files as globs
return entryFiles
.reduce((p, m) => p.concat(glob.sync(m, {nonull: true})), [])
.map(f => Path.resolve(f));
}

@davidnagli
Copy link
Contributor

Oh cool didn’t notice that 👍

@devongovett devongovett added this to the v1.8.0 milestone Apr 2, 2018
@devongovett devongovett self-assigned this Apr 2, 2018
@briandk
Copy link

briandk commented Apr 4, 2018

@devongovett I would love to see this feature! Unfortunately, It looks like the Appveyor build is failing a Vue.js integration test:

vue should produce a vue bundle using preprocessors:
C:\projects\parcel\test\integration\vue-preprocessors\pre-processors.vue:5:22

I'm kind of a first-timer here, but is there anything I can do to help?

@fathyb
Copy link
Contributor

fathyb commented Apr 4, 2018

@briandk: it seems unrelated to the PR, tracked by #1110 about it and it should be fixed by #1090.

Feel free to check out our 👶 Good First Issue though, contributions are more than welcome :)

@FGRibreau
Copy link

FGRibreau commented Apr 14, 2018

For those who wish to try it #cuttingEdge:

"scripts": {
    "postinstall": "cd node_modules/parcel-bundler && npm i"
},
"devDependencies": {
    "parcel-bundler": "github:parcel-bundler/parcel#multi-entry"
}

prelude.min.js was not there (note: it's a file generated through yarn minify from parcel npm build step) so I had to force it.

@icai
Copy link

icai commented Apr 18, 2018

@devongovett support middleware as the following ❓

const bundler = new Bundler('./pages/**/*.html', {
  outFile: '*.html',
  publicUrl: './'
});

app.use(bundler.middleware());

https://en.parceljs.org/api.html#middleware

@nicolasdelfino
Copy link

@fathyb is it in fact #1090 or you think it's something else preventing the merge?

@devongovett devongovett merged commit 7cbbeef into master May 1, 2018
@devongovett devongovett deleted the multi-entry branch May 1, 2018 15:00
@tylerlong
Copy link

tylerlong commented Jun 11, 2018

But now I have to access http://localhost:1234/index.html instead of http://localhost:1234.

Could it be a little smarter to know that I want index.html?

@yamsellem
Copy link

I don't find any mention of this (great) feature in the doc.
Do I miss something?

If I don't, maybe adding a line or two in the api section will greatly help (I've searched among github issues before discovering the feature was already there).

@safareli
Copy link

safareli commented Jul 6, 2018

But now I have to access http://localhost:1234/index.html instead of http://localhost:1234.

is there an issue it?

@redbulled
Copy link

redbulled commented Jul 28, 2018

@devongovett thank you for such an amazing bundler.

Entry points can be passed to parcel as a list of files, or as a glob or list of globs. e.g. parcel *.html

pls write it somewhere on your site. Because it is such a great future and I was amazed when I found it

@matthewmueller
Copy link

matthewmueller commented Aug 1, 2018

But now I have to access http://localhost:1234/index.html instead of http://localhost:1234.

Second this.

parcel index.html correct resolves:

http://localhost:1234 => http://localhost:1234/index.html

parcel index.html app/index.html no longer resolves that. Should serve:

http://localhost:1234 => http://localhost:1234/index.html
http://localhost:1234/app => http://localhost:1234/app/index.html

@sgf
Copy link

sgf commented Aug 7, 2018

waiting for use this feature 😂

@elsheepo
Copy link

elsheepo commented Sep 21, 2018

when I bundle multiple entry points, I get my SCSS converted to CSS and bundled with bootstrap.css as expected and jquery.js/bootstrap.js/custom.js bundled on the first html file in alphabetical order, and the rest only HTML & JavaScript, it is not adding the <link href="{name}{hash}.css"> to subsequent pages.
I have tried these...
parcel *.html and parcel index.html about.html contact.html documentation.html repository.html

fyi: each page (index.html, about.html, etc) links to index.js like so...
<script src="./index.js"></script>

and the contents of index.js are...

import './vendor/bootstrap/css/bootstrap.min.css'
import './vendor/fontawesome-free/css/all.min.css'
import './scss/custom.scss'
import './vendor/jquery/jquery.min.js'
import './vendor/bootstrap/js/bootstrap.bundle.min.js'
import './js/custom.js'

So to reiterate, the first entry point (in alphabetical order, in my case it chooses about.html) gets links to both the bundled css & javascript, but the rest of the pages only get a link to the bundled javascript.

Here are the resulting about.html and index.html after having executed parcel *.html
notice how on line 16 of about.html a link is inserted into the <head> referring to the bundled css. Where as in subsequent html files, such as index.html there is not.

@ivanmalagon
Copy link

@elsheepo I have the same issue but in my case I could solve it writing <link href="../src/style/custom.scss" rel="stylesheet"> in each HTML instead of setting import './style/custom.scss in a JS file.
This way, the SCSS gets processed and added to every HTML file that uses it.

@wesbos
Copy link

wesbos commented Feb 27, 2019

I just added this to the docs. Would love to hear if anyone has a solution to the index.html no longer working with multiple entry points

@shaunakv1
Copy link

Looks like this is still an issue

parcel index.html report.html --https --open opens: https://localhost:1234 which doesn't work.

https://localhost:1234/index.html does however. It's a minor inconvenience, which only effects in dev mode, but def one that confuses others developers on the team when adding the multiple entry points for the first time. Plus now you have to go to the browser and type index.html

@matias89
Copy link

matias89 commented Aug 27, 2019

when I bundle multiple entry points, I get my SCSS converted to CSS and bundled with bootstrap.css as expected and jquery.js/bootstrap.js/custom.js bundled on the first html file in alphabetical order, and the rest only HTML & JavaScript, it is not adding the <link href="{name}{hash}.css"> to subsequent pages.
I have tried these...
parcel *.html and parcel index.html about.html contact.html documentation.html repository.html

fyi: each page (index.html, about.html, etc) links to index.js like so...
<script src="./index.js"></script>

and the contents of index.js are...

import './vendor/bootstrap/css/bootstrap.min.css'
import './vendor/fontawesome-free/css/all.min.css'
import './scss/custom.scss'
import './vendor/jquery/jquery.min.js'
import './vendor/bootstrap/js/bootstrap.bundle.min.js'
import './js/custom.js'

So to reiterate, the first entry point (in alphabetical order, in my case it chooses about.html) gets links to both the bundled css & javascript, but the rest of the pages only get a link to the bundled javascript.

Here are the resulting about.html and index.html after having executed parcel *.html
notice how on line 16 of about.html a link is inserted into the <head> referring to the bundled css. Where as in subsequent html files, such as index.html there is not.

Man, I had the same issue. I solved it doing this: instead of call index.js in each HTML file, I created a js for each html, and import index.js on each file.
In your case, you should create a home.js and about.js, and import in both index.js. Then, you should use <script src="./home.js"></script> in your index.html and <script src="./about.js"></script> in your about.html. This is the best solution that I found and works well. Best regards.

@ProLoser
Copy link

ProLoser commented Jan 12, 2023

Doesn't multiple entrypoints require different respective exit points? I do not want all my entrypoints to yield one dist file.

Sometimes I'm transpiling a module or library and then converting it to a string to be injected at runtime. This is currently something I'm unable to do for parcel. Perhaps with a custom prefix? But then I cannot ship this code if it's consumed as esm

Alternatively, I use transpilation to pre-compile static versions of my page namespaced under a categorization folder and would like to run those in parallel.

I can do this with rollup (awkwardly) but cannot do it in Parcel

@devongovett
Copy link
Member Author

You can do it with targets. Each target can have a source field that defines its entry point, and a top level field for the output or a distDir within the target. https://parceljs.org/features/targets/#package.json%23targets.*.source

@ProLoser
Copy link

Can you use glob patterns to handle a parallel series of sources with parallel targets (like statically generated variations of a website)

@rohit404404
Copy link

rohit404404 commented Apr 10, 2023

Looks like this is still an issue

parcel index.html report.html --https --open opens: https://localhost:1234 which doesn't work.

https://localhost:1234/index.html does however. It's a minor inconvenience, which only effects in dev mode, but def one that confuses others developers on the team when adding the multiple entry points for the first time. Plus now you have to go to the browser and type index.html

Any resolution to this issue yet? there is solution discussed here. HOwever, seems it does not work. https://stackoverflow.com/questions/69029045/deploying-problem-with-multiple-html-files-parcel

@wesbos
Copy link

wesbos commented Apr 10, 2023

No fix - I ended up having to move to Vite just to get this feature unfortunately

@ProLoser
Copy link

Vite is just roll-up with a bunch of defaults.

I ended up going back to basics and doing everything in roll-up and gulp for more granular control. KISS

Tired of wasting most of my time with build tooling instead of just building.

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

Successfully merging this pull request may close these issues.

Support for multiple entry points.