miyasudokoro
miyasudokoro

Reputation: 1745

How to use webpack externalsType module

There is no documentation on how to declare the external itself when you use externalsType = module, so I've been trying everything I can think of.

Here is a version that works with the version of the CDN that does not export an ES6 module.

{
    "experiments": { outputModule: true },
    "output": {
         "path": path.join( __dirname, 'dist' ),
         "[name].mjs",
         "library": { type: "module" }
    }
   "externalsType": "var",
   "externals": {
       "/local/library.min.js": "library"  <-- this is the non-ES6-module version of the CDN
   }
}

// builds the correct output files

What I want to do instead is actually import the CDN's ES6 module version.

Some of the myriad things I have tried:

1.

   "externalsType": "module",
   "externals": {
       "/local/library.min.mjs": "https://cdn-path/library.min.mjs"
   }

// The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module' while analysing module external "https://cdn-path/library.min.mjs" for concatenation

   "externalsType": "module",
   "externals": {
       "/local/library.min.mjs": "library@https://cdn-path/library.min.mjs"
   }

// The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module' while analysing module external "library@https://cdn-path/library.min.mjs" for concatenation

   "externalsType": "module",
   "externals": {
       "/local/library.min.mjs": "import library from https://cdn-path/library.min.mjs"
   }

// The target environment doesn't support 'import()' so it's not possible to use external type 'import'

   "externalsType": "import",
   "externals": {
       "/local/library.min.mjs": "import library from https://cdn-path/library.min.mjs"
   }

// The target environment doesn't support 'import()' so it's not possible to use external type 'import'

   "externalsType": "module",
   "externals": {
       "/local/library.min.mjs": "import * from https://cdn-path/library.min.mjs"
   }

// The target environment doesn't support 'import()' so it's not possible to use external type 'import'

    externalsType: 'module',
    externals: [
        function( { _context, request }, callback ) {
            if ( request === '/local/library.min.mjs' ) {
                return callback( null, 'https://cdn-path/library.min.mjs', 'module' );
            }
            return callback();
        }
    ]

// The target environment doesn't support EcmaScriptModule syntax so it's not possible to use external type 'module' while analysing module external "https://cdn-path/library.min.mjs" for concatenation

I looked inside the webpack source code but could not find anything that had been written to allow for this.

I have a bug report all written up and ready to submit if nobody can answer this question today. Thanks for your help.

Upvotes: 5

Views: 7271

Answers (2)

hronro
hronro

Reputation: 1327

By checking the source code of webpack, I found you need to set output.environment.module to true to tell webpack ECMAScript Module syntax is supported in your environment:

{
    "experiments": { outputModule: true },
    "output": {
         "path": path.join( __dirname, 'dist' ),
         "library": { type: "module" },
         environment: { module: true },
    }
   "externalsType": "module",
   "externals": {
       "/local/library.min.js": "https://cdn-path/library.min.mjs"
   }
}

However, in the current version of webpack(v5.38.1), "externalsType": "module" is not implemented at all, so you will still got an error from webpack.

Luckily, "externalsType": "import" is supported in current version of webpack, although it might be less efficient than the "externalsType": "module" (it uses dynamic import instead of import). As a workaround, we can use "externalsType": "import" for now:

{
    "experiments": { outputModule: true },
    "output": {
         "path": path.join( __dirname, 'dist' ),
         "library": { type: "module" },
         environment: {
           module: true,
           dynamicImport: true,   // Note you need to enable `dynamicImport ` here
         },
    }
   "externalsType": "import",
   "externals": {
       "/local/library.min.js": "https://cdn-path/library.min.mjs"
   }
}

Upvotes: 10

miyasudokoro
miyasudokoro

Reputation: 1745

The answer is that it isn't implemented yet. I don't understand the logic behind documenting it as existing when it doesn't. What a waste of time.

externalsType: 'module',
externals: [
   function( { _context, request }, callback ) {
       if ( request === '/local/library.min.mjs' ) {
           return callback( null, 'https://cdn-path/library.min.mjs', 'module' );
       }
       return callback();
   }
],
experiments: {
    outputModule: true
},
output: {
    path: path.join( __dirname, 'dist' ),
    filename: '[name].js',
    library: {
        type: 'module'
    },
    environment: {
        // The environment supports ECMAScript Module syntax to import ECMAScript modules (import ... from '...').
        module: true
    }
}

// Module external type is not implemented yet

Upvotes: 4

Related Questions