Vega-lite: Support es6 module import

Created on 23 Jun 2018  路  25Comments  路  Source: vega/vega-lite

Provide an es6 module for the project. Provide access via unpkg.com using the ?module form. See D3 repo.

Wontfix

Most helpful comment

fwiw import * as vega from "vega-lib" works here on 4.3.0

All 25 comments

Vega-Lite can be imported as an es6 module. Please describe the issue in more detail so that we can resolve it.

I used https://unpkg.com/vega-lite/ to inspect the npm package. The build/ dir had only a UMD, which cannot be imported as an es6 module. I looked at https://unpkg.com/vega-lite which indeed was that minified UMD.

The package.json was setup with the module: field so https://unpkg.com/vega-lite?module should work. Trying that produced:

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var aggregate = tslib_1.__importStar(require("./aggregate"));
exports.aggregate = aggregate;

.. and a lot more like this.

Finally I tried three possible imports within an html test, all of which failed.

<head>
    <title>VegaTest</title>
</head>
<body>
    <script type="module">
        // Uncaught SyntaxError: The requested module 'https://unpkg.com/vega-lite?module' does not provide an export named 'default'
        // import vega from 'https://unpkg.com/vega-lite?module'

        // Uncaught SyntaxError: The requested module 'https://unpkg.com/vega-lite?module' does not provide an export named 'vega'
        // import {vega} from 'https://unpkg.com/vega-lite?module'

        // import('https://unpkg.com/vega-lite?module')
        // .then(module => console.log(module))
    </script>
</body>
</html>

It's possible I simply am doing it wrong! I didn't find mention of this in a quick look at the docs so I'm possibly using the wrong approach.

Could you point me to how to do this correctly? Thanks!

I don't think you can use es6 imports in the browser. Instead, import the bundle (https://unpkg.com/[email protected]/build/vega-lite.js).

Do you mean:

import vega from 'https://unpkg.com/[email protected]/build/vega-lite.js'

.. results in: Uncaught SyntaxError: The requested module 'https://unpkg.com/[email protected]/build/vega-lite.js' does not provide an export named 'default'

Also

    import { vega } from 'https://unpkg.com/[email protected]/build/vega-lite.js'

produces: Uncaught SyntaxError: The requested module 'https://unpkg.com/[email protected]/build/vega-lite.js' does not provide an export named 'vega'

    import * as vega from 'https://unpkg.com/[email protected]/build/vega-lite.js'

produces: vega-lite.js:4 Uncaught TypeError: Cannot set property 'vl' of undefined at isArray(vega - lite.js: 4)

Maybe I misunderstand what you meant?

I'm being dense, I guess, but

import * as vlImport from 'vega-lite';

doesn't tell me anything. This is a bare import, and I presume preprocessed by TS and your workflow. I tried the equivalent imports above.

Could you simply post a working import to unpkg.com? Thanks.

I have never seen an import from unpkg.com. Can you post a working example with D3?

Love to! All this is pretty exotic. I've been pouring over d3's workflow and wow.

<html>
<head>
    <title>D3 import</title>
</head>

<body>
    <script type="module">
        import * as d3 from 'https://unpkg.com/d3?module'

        window.d3 = d3 // to look at it in the console.
    </script>
</body>

</html>

If you'd like to see vega-light on unpkg: http://unpkg.com/vega-lite shows the minified umd.

To see the "dashboard", just add a final "/": http://unpkg.com/vega-lite/

The issue is that we don't compile es6 javascript but instead es5 because es6 is not widely supported yet. We will change that in the future but not yet.

For now, Don't use module and just load vega-lite into the global namespace.

<script src="https://unpkg.com/vega-lite"></script>

Does "wontfix" mean forever? I'll just move on if so.

We'll change this eventually but right not only a fraction of packages support the new import syntax and the fix to use <script src="https://unpkg.com/vega-lite"></script> is easy. Luckily this turned out to not be a bug so there is no urgency. Having said that, if we see adoption of the new import syntax is other libraries, we will follow. Changing to es2015 imports only takes two lines of changes in our building scripts.

fwiw import * as vega from "vega-lib" works here on 4.3.0

Vega-Lite 3 ships with es2015 imports and es6 code.

TL;DR: Vega-lite still does not import correctly for me. I may be doing it incorrectly, let me know, thanks!

Details:
Vega-lite still does not import correctly. If I simply put this in the browser's url field:

https://unpkg.com/vega-lite?module

.. I get:

import pkg from "../package.json?module";
import { normalize } from "./normalize?module";
const version = pkg.version;
export { compile } from "./compile/compile?module";
export { extractTransforms } from "./transformextract?module";
export { normalize, version };

..which does not appear to be a correctly formatted JS module.

So I put this in a trivial test page:

<!DOCTYPE html>
<html>
    <head>
        <title>Vega Test</title>
    </head>
    <body>
        <script type="module">
            import * as vega from 'https://unpkg.com/vega-lite?module'
            console.log('vega:', vega)
        </script>
    </body>
</html>

.. but when using it, I get a "Forbidden" error:

GET https://unpkg.com/[email protected]/build/package.json?module net::ERR_ABORTED 403

Looking at your package.json,

  "main": "build/vega-lite.js",
  "unpkg": "build/vega-lite.min.js",
  "jsdelivr": "build/vega-lite.min.js",
  "module": "build/src/index",

the module should be at: "build/src/index", which unfortunately is not a complete path!

I think many users are using workflow that makes this all work for them, but for me, just trying to get the JS module fails.

Is this a bug with Vega-Lite or with unpkg?

Good question! Could you give me a jsdelivr url (or any other server) to the module form of vega-lite and I'll try it? Actually, it may require a few urls? .. the script forms I think use three?

I think the problem is that none of the modules of https://unpkg.com/[email protected]/build/src/index.js have complete paths which is a requirement of es6 modules:

import pkg from '../package.json';
import { normalize } from './normalize';
const version = pkg.version;
export { compile } from './compile/compile';
export { extractTransforms } from './transformextract';
export { normalize, version };
//# sourceMappingURL=index.js.map

Unpkg may be trying to normalize these and failing?

Well, no, that just takes me to a website, sorta a dashboard. Could you give me a url directly to the es6 module file(s)?

The page has a list with all the files that are accessible through jsdelivr.

Sweet, nice dashboard.

Looking at the package.json, presumably build/src/index.js is the file I want, yes?

Using the prior test w/ this path:

<!DOCTYPE html>
<html>
    <head>
        <title>Vega Test</title>
    </head>

    <body>
        <script type="module">
            import * as vega from 'https://cdn.jsdelivr.net/npm/[email protected]/build/src/index.js'
            console.log('vega:', vega)
        </script>
    </body>
</html>

I get several errors:

Is this the wrong file? It appears to be a module but does not have complete url paths, thus illegal syntax. It also imports package.json which is not legal either.
https://cdn.jsdelivr.net/npm/[email protected]/build/src/index.js:

import pkg from '../package.json';
import { normalize } from './normalize';
const version = pkg.version;
export { compile } from './compile/compile';
export { extractTransforms } from './transformextract';
export { normalize, version };
//# sourceMappingURL=index.js.map

This is fairly obviously a file needing transformation by your workflow tools, right? Every line is other than const version .. is illegal!

I did try adjusting the url's to be relative paths, and did get modules, but again, without complete/legal paths, try this:
https://cdn.jsdelivr.net/npm/[email protected]/build/src/transformextract.js

So there appears to be issues with the workflow building the modules.

Sorry to be so verbose! I think the problem we're facing is this:
https://www.typescriptlang.org/docs/handbook/module-resolution.html

Typescript has a very sophisticated module resolution system which presumes use of "names" rather than "paths" and uses several resolution stunts to convert a name into a path. Note the use of relative vs non-relative.

My guess is that the ts compiler is presuming a resolution capability in the CDNs. Ditto the ability to import json, which I believe ts also allows.

Thus we need to figure out how to set up ts's configuration to produce legal es6 modules.

Note that we are reading a reason file as a module, which works because we use a json plugin in rollup. Can you use the bundle we compile instead of the index.js file?

I would much prefer that if it is a module rollup! I looked for one and didn't find it. And looking at the rollup.config.js, I found only one output, one for the umd:

export default {
  input: 'build/src/index.js',
  output: {
    file: 'build/vega-lite.js',
    format: 'umd',
    sourcemap: true,
    name: 'vl'
  },
  plugins: [disallowedImports(), nodeResolve({browser: true}), commonjs(), json(), sourcemaps()]
};

It isn't obvious, but rollup can rollup not only to script bundles but also to module bundles. I was surprised at that but now offer not only a umd rollup for node and browser script tags, but also into an es6 bundle for "import" use.

So if you add a second output segment, it can have format:'es'. Mine looks like:

export default {
    input: 'src/AS.js',
    output: [
        {
            file: 'dist/agentscript.umd.js',
            format: 'umd',
            name: 'AS',
        },
        {
            file: 'dist/agentscript.esm.js',
            format: 'es',
        },
    ],
}

Ahh, I see. Can you send a PR to update our rollup scripts? We can make a release with different bundles then.

Was this page helpful?
0 / 5 - 0 ratings