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

Feature request: Serving arbitrary content #945

Closed
swansontec opened this issue Mar 5, 2018 · 9 comments
Closed

Feature request: Serving arbitrary content #945

swansontec opened this issue Mar 5, 2018 · 9 comments
Labels

Comments

@swansontec
Copy link

swansontec commented Mar 5, 2018

This is a 🙋 feature request.

🔦 Context

I am developing an application which makes use of an iframe component. The iframe content comes from a third party, so I don't want to bundle / process it in any way. When I use the Parcel dev server, I would still like to serve these assets to the browser, though.

💻 Code Sample

My original idea was to place the iframe assets into their own directory under dist:

src/
  index.html
  index.js
dist/
  index.html
  7c9f3a4e8f6a49bead9b397b6a44da06.js
  assets/ # I copied my third-party code in here...
    index.html
    frame.css 

Given this folder layout, I would like to do something like this in my code:

function MyComponent () {
  return <iframe src='./assets/index.html' />
}

However, the parcel dev server (started by parcel src/index.html) doesn't seem to be serving the assets folder, so when I place that component on my page, I don't actually get the iframe contents (In fact, accessing http://localhost:1234/assets/index.html just returns the outer, bundled index.html, so I get an infinite recursion of frames inside of frames. Cool, but not what I wanted. 🤷‍♂️).

Would it make sense for parcel to serve random files manually copied into the dist folder? Is there a better way to accomplish this? Thanks.

@swansontec
Copy link
Author

I'm not really sure what bug #371 is asking, but it's possible that this is related.

@davidnagli
Copy link
Contributor

You should never manually modify the dist directory. Try moving that dist/assets directory to src/assets, so Parcel will be able to properly resolve it.

@DeMoorJasper
Copy link
Member

DeMoorJasper commented Mar 5, 2018

Normally parcel should catch iframe tags, however this is JSX I suppose?
The server is basically a simple http server, it serves whatever you put in dist, however in your example case the code is just incorrect according to how strict parcel works.

the correct code would be this:

function MyComponent () {
  const src = require('./assets/index.html');
  return <iframe src={src} />
}

Or this if u like it shorter

function MyComponent () {
  return <iframe src={require('./assets/index.html')} />
}

@davidnagli
Copy link
Contributor

davidnagli commented Mar 5, 2018

@DeMoorJasper Parcel would still resolve ./assets/index.html relative to the entry point (which is in src)

@DeMoorJasper
Copy link
Member

DeMoorJasper commented Mar 5, 2018

@davidnagli Ow didn't see that structure, well now i'm kinda confused at why this would even be a feature, this seems like an extremely narrow use-case?

Unless it makes sense to move the assets folder to the src folder than it would make sense again to bundle it up with everything else.
Otherwise the original copy paste method would be the only solution i guess

@swansontec
Copy link
Author

swansontec commented Mar 5, 2018

The server is basically a simple http server, it serves whatever you put in dist, however in your example case the code is just incorrect according to how strict parcel works.

I see. In that case, is it a bug that asking for any HTML file always returns a copy of index.html, regardless of the path? I would expect a 404 error when asking for something like /foo/bar.html, but that's not happening.

the correct code would be this:

Ok, so I went ahead and tried your suggestion in a fresh directory:

package.json:

{
  "private": true,
  "scripts": {
    "start": "parcel index.html"
  },
  "dependencies": {
    "preact": "^8.2.7"
  },
  "devDependencies": {
    "parcel-bundler": "^1.6.2"
  }
}

index.html:

<html>
<body>
  <script src="./index.js"></script>
</body>
</html>

index.js:

import { h, render } from "preact";
import frameHtml from "./frame.html";

render(h("iframe", { src: frameHtml }), document.body);

frame.html:

<html>
<body>
  <p>Hello world!</p>
</body>
</html>

However, the import statement simply crashes the browser at runtime:

Uncaught (in promise) Error: Cannot find module '6'
    at newRequire (8044e941c668efeac0cf0d2af2f974f9.js:33)
    at newRequire (8044e941c668efeac0cf0d2af2f974f9.js:22)
    at localRequire (8044e941c668efeac0cf0d2af2f974f9.js:48)
    at Object.require.4.preact (preact.esm.js:794)
    at newRequire (8044e941c668efeac0cf0d2af2f974f9.js:42)
    at localRequire (8044e941c668efeac0cf0d2af2f974f9.js:48)
    at preact.esm.js:975
    at <anonymous>

Other variations I tried:

  • Using const frameHtml = require("./frame.html"); instead of the import syntax. The same crash happens, but with different line numbers.
  • Removing everything from the JS except the import frameHtml from "./frame.html"; line. The runtime crash still happens with just the bare HTML import (no Preact anywhere).
  • Renaming 'frame.html' to 'foo.html' on disk. Parcel refused to bundle with the missing file, as expected. There was no runtime JS error, since there was no bundle being served.
  • Replacing 'frame.html' with an image file (frame.jpg) actually worked, and the image appeared in the iframe with no runtime errors.

So, importing HTML from within JS doesn't seem to work in Parcel the moment.

@DeMoorJasper
Copy link
Member

DeMoorJasper commented Mar 5, 2018

@swansontec Hoped it would work, although html imports would be weird in a sense, as some people might want to use the actual html in their js and some people would want the link to the actual file, I guess this could spark a discussion to add something like this:

Html assets imported from Javascript, might than look something like this

exports.html = '<html><!-- some html code --></html>';
exports.uri = '/dist/aa4ez65e4aze4a654ze.html';

@swansontec
Copy link
Author

I see. Given this situation, it looks like the only way to have a JS-managed iframe using current Parcel is to host the iframe contents on some sort of CMS. Then Javascript can just do something like <iframe src='https://other-server/frame-content.html'>, and Parcel doesn't get involved.

For now, putting the iframe content into the src directory doesn't work, since Parcel can't bundle HTML into JS, and putting the content into dist directory doesn't work, because Parcel isn't serving it properly. Long term, it looks like Parcel would prefer putting the content into src so it can run through the bundling pipeline like anything else. The second option, manually copying the data into dist, isn't something Parcel wants to officially support.

I'm not sure the third-party code will survive a trip through Parcel, since it has already been bundled using Webpack or whatever those guys are using. If it does survive, though, the first option sounds reasonable to me too. Maybe the solution is a plugin that simply adds files to the bundle without transforming them in any way.

@stale
Copy link

stale bot commented Jan 17, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Stale Inactive issues label Jan 17, 2020
@github-actions github-actions bot closed this as completed Feb 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants