Search code examples
javascriptecmascript-6es6-modulesgoogle-closure-compiler

How do I specify the path for ES6 import in Google Closure Compiler?


Using the latest version of Closure Compiler, I can't seem to get ES6 modules to load no matter how I specify the module's path in the import statement.

To test this, I created two very simple files in the same directory.

defaults.js:

const defaults = {color: "#F44336"}
export {defaults}

test.js:

import {defaults} from 'defaults.js'
console.log(defaults.color)

When I just run test.js without attempting to process it with Closure Compiler, it works as expected and imports the module. But trying to compile it produces the error:

test.js:1:0: ERROR - [JSC_JS_MODULE_LOAD_WARNING] Failed to load module "defaults"

This is the command line I'm using:

compiler \
--module_resolution NODE \
--compilation_level ADVANCED \
--language_in ECMASCRIPT_2020 \
--language_out ECMASCRIPT_2020 \
--js test.js

I've tried specifying the path to the module file in test.js as a fully qualified absolute path, and various forms of relative path, and nothing has worked. I also tried adding the module file as a --js option for the compiler, but no dice.

It seems like such a simple thing but I have not found a solution by extensive googling, either. Can anyone tell me what I'm missing?


Solution

  • I recreated your files (note the difference):

    defaults.js

    const defaults = {color: "#F44336"}
    export {defaults}
    

    test.js

    import {defaults} from './defaults.js' // relative path!
    console.log(defaults.color)
    

    Compilation

    You MUST specify all files involved in the compilation with --js.

    $ cc --module_resolution NODE --compilation_level ADVANCED --js defaults.js --js test.js
    console.log("#F44336");
    

    cc is just an alias to my copy of the Closure compiler


    Addendum

    I'm pretty sure that your biggest mistake has to be this:

    import {defaults} from 'defaults.js'
    

    This was never going to load the file on disk but instead was looking for a NPM package called defaults.js in your dependencies.