parcel-bundler / parcel

The zero configuration build tool for the web. πŸ“¦πŸš€
https://parceljs.org
MIT License
43.39k stars 2.27k forks source link

dev server: no content-type for unknown file extensions #5066

Open ranisalt opened 4 years ago

ranisalt commented 4 years ago

πŸ› bug report

πŸŽ› Configuration (.babelrc, package.json, cli command)

.parcelrc

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.ftl": ["@parcel/transformer-raw"]
  }
}

πŸ€” Expected Behavior

File should be served with an text/plain MIME type, or at least application/octet-stream.

😯 Current Behavior

Firefox errors with:

Loading module from β€œhttps://localhost:1234/en.c67692ff.ftl” was blocked because of a disallowed MIME type (β€œβ€).

It is possible to manually access the URL and download the file correctly.

πŸ’ Possible Solution

Don't know, maybe a way to manipulate dev server headers? I could set up the correct MIME type if behind a reverse proxy, but not for development purposes.

πŸ”¦ Context

I am trying to load translation files for Fluent in a Parcel project, but since those are plain text files with a custom extension .ftl, they are served without an explicit MIME type and browsers block it for safety purposes.

πŸ’» Code Sample

import en from 'url:./translations/en.ftl';
import pt from 'url:./translations/pt.ftl';

const Languages = {
    en: {
        locale: 'en',
        getMessages: () => import(en) as Promise<string>,
    },
    pt: {
        locale: 'pt',
        getMessages: () => import(pt) as Promise<string>,
    },
    // several of those
};

data-url and raw imports do not work either.

🌍 Your Environment

Software Version(s)
Parcel 2.0.0-beta.1
Node 14.8.0
npm/Yarn yarn 1.22.4
Operating System Arch Linux
ranisalt commented 4 years ago

It works with fetch(...).then(r => r.text()) though. I was tackling it the wrong way for hours :laughing:

However, it's weird to "import" the file just for the URL, then pass it to fetch. Is there a cleaner way to write this, without feeling too repetitive?

import en from 'url:./translations/en.ftl';
import pt from 'url:./translations/pt.ftl';

const Languages = {
    en: {
        locale: 'en',
        getMessages: () => fetch(en).then(r => r.text()),
    },
    se: {
        locale: 'pt',
        getMessages: () => fetch(pt).then(r => r.text()),
    },
};

I'm thinking maybe if it was possible to parse fetch for relative URLs:

fetch('data:./en.ftl').then(r => r.text())
mischnic commented 4 years ago

We just call out to https://github.com/vercel/serve-handler

https://github.com/parcel-bundler/parcel/blob/1e5321fc1a0d01eaad407e335276a2899fe72f62/packages/reporters/dev-server/src/Server.js#L252-L265

Seems to happen with https://github.com/vercel/serve as well:

niklas@nmb:~/Desktop $ curl -v localhost:5000/x.ftl
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 5000 (#0)
> GET /x.ftl HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 0
< Content-Disposition: inline; filename="x.ftl"
< Accept-Ranges: bytes
< ETag: "bf3c1d394f6493fce2e2f73e074f9b10f176a29e"
< Date: Tue, 25 Aug 2020 07:42:19 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
<
* Connection #0 to host localhost left intact
* Closing connection 0
mischnic commented 4 years ago

Chrome and Safari don't complain, very odd

mischnic commented 4 years ago

However, it's weird to "import" the file just for the URL, then pass it to fetch. Is there a cleaner way to write this, without feeling too repetitive?

Unless you create a Parcel Transformer plugin that detects calls like fetch("http....") (which should be rather easy to do), no.

ranisalt commented 4 years ago

Chrome and Safari don't complain, very odd

My Firefox configuration is tightened for privacy, it might be the case that it interferes.

Unless you create a Parcel Transformer plugin that detects calls like fetch("http....") (which should be rather easy to do), no.

That's ok for now, maybe if I have issues with that in the future I will try! :smile: thanks.

mischnic commented 4 years ago

Wait, import(en) would never work, that only works for JS files.

What I tested was putting localhost:5000/x.ftl in the URL bar and looking in the console, where only Firefox complained.


We should still look into making application/octet-stream the fallback value.