Parcel: Can't load static asset (CSV file for instance) asynchronously

Created on 13 Feb 2018  路  6Comments  路  Source: parcel-bundler/parcel

馃悰 bug report

I normally use d3.tsv, d3.csv or d3.jetpack.loadData to load a CSV, JSON or TSV data static asset asynchronously. For instance the d3.jetpack.loadData (url, function(error, response) {}), the response parameter would normally contain the data file as an object, but now that I use ParcelJs, response only contains the HTML of the current page as an array.

The code below illustrates an example that does work without ParcelJs, but has different behaviour with ParcelJs.

馃帥 Configuration (.babelrc, package.json, cli command)

{
    "presets": ["env"]
}
{
  "name": "",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "parcel index.html",
    "build": "parcel build index.js"
  },
  "repository": {
    "type": "git",
    "url": "t"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^8.0.0",
    "babel-preset-env": "^1.6.1",
    "postcss-modules": "^1.1.0",
    "posthtml-img-autosize": "^0.1.1",
    "standard": "^10.0.3"
  },
  "dependencies": {
    "d3-array": "^1.2.1",
    "d3-jetpack": "^2.0.16",
    "d3-request": "^1.0.6"
  }
}

馃 Expected Behavior

In the code sample, the expected value of res should be the tsv-file as object.

馃槸 Current Behavior

In the code sample, the current value of res is the HTML of the current page as an array.

馃拋 Possible Solution

馃敠 Context

I'm trying to load a static asset (CSV, TSV or JSON file) asynchronously. It's a rather large file, hence the asynchronous loading.

馃捇 Code Sample

import { tsv } from 'd3-request'

tsv('./data/data.tsv', (err, res) => {
  if (err) {
    console.error(err)
  }
  console.log(res)
})

馃實 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.5.1
| Node | 8.9.4
| npm | 5.6.0
| Operating System | MacOS High Sierra 10.13.3

Most helpful comment

But I do find it confusing that the behaviour of a function (XHR request) is different, just by using ParcelJs

To (hopefully) clear this matter up: when a file doesn't exist, parcel serves index.html. This is so that client-side-routing on single page apps works.

All 6 comments

Another example, using just the standard XMLHttpRequest has the same behaviour. I would expect the contents of the tsv file to be logged to the console, but what happens is that the contents of the current HTML page is logged to the console.

function reqListener () {
  console.log(this.responseText);
}

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "./data/data.tsv");
oReq.send();

what about changing your example to:

import { tsv } from 'd3-request';

tsv(require('./data/data.tsv'), (err, res) => {
  if (err) {
    console.error(err)
  }
  console.log(res)
})

This should work as require should resolve to the new path...

I'm not sure if there is a generic way to fix this, besides using the proper requires, as this would probably introduce some bugs.

You could also use fs.readfileSync if that's preferred

I had this problem as well (fetching an exotic data file). Solved it with a custom dev server:

const Bundler = require('parcel-bundler')
const express = require('express')

let bundler = new Bundler('src/index.htm')
let app = express()

app.use('/api', express.static('.'));

app.use(bundler.middleware())

app.listen(Number(process.env.PORT || 1234))

Something like https://github.com/webpack-contrib/copy-webpack-plugin would be useful. (For example, you can't require a pdf file.)

EDIT:
Is there any documentation that with fs.readfileSync, the content gets inlined?

@DeMoorJasper should that work with the built in dev server? So far I haven't been able to get require to work, nor have I been able to get fs.readFileSync to work. For the latter I get Uncaught TypeError: _fs2.default.readFileSync is not a function

@mischnic I'll try the custom dev server. But I do find it confusing that the behaviour of a function (XHR request) is different, just by using ParcelJs

@DeMoorJasper ah, sorry, had a small typo in the path, the require does work! Thanks!! I guess that's a good enough workaround for now.

But I do find it confusing that the behaviour of a function (XHR request) is different, just by using ParcelJs

To (hopefully) clear this matter up: when a file doesn't exist, parcel serves index.html. This is so that client-side-routing on single page apps works.

Was this page helpful?
0 / 5 - 0 ratings