简体   繁体   中英

Avoid the `default` object when exporting a Node module for the browser with Webpack

I'm sure this is simple but it's confounding me! I maintain a few NPM modules for browser convenience functions which work just fine when a parent app uses require or import and then bundles them with Webpack. But, in deference to the myriad user environments out there, I'd like to provide a standalone bundle in a dist directory in Github for those who need to include it in a <script> tag.

The problem, in short, is that when I use Webpack to make a browser-ready module, per the Webpack instructions , the object exposed to window is always a Module that has a single property, default , that contains the function itself.

For example, my elastic-svg , which is a super-simple tool to make SVGs resize like div s and intelligently resize the contents, exports like so:

export default function elasticSVG(selector, opts) { source

The Webpack config, which I keep outside the module so as not to muddy the source, looks like this:

{
  entry: './index.js',
  output: {
    path: path.resolve(process.cwd(), "./dist"),
    filename: 'elasticSVG.js',
    library: 'elasticSVG',
    libraryTarget: 'umd'
  },
  mode: 'development',
  devtool: 'inline-source-map',
  externals: [nodeExternals()],
  // relevant modules and rules etc.

This is all fine and good, but when I test the file in dist/elasticSVG.js from examples/demo.html , I see this:

在此处输入图片说明

Surely there's a simple way to export the module such like, like a normal, old-fashioned module, window.elasticSVG is the function itself? This may solve another issue I don't under, which is why this does work in Node:

import elasticSVG from 'elastic-svg';

but this doesn't work:

import * as elasticSVG from 'elastic-svg';

Not a big problem, but I'd like to understand why. It's difficult to Google since the environment changes so rapidly! I've tried a variety of other export syntaxes without much success. Thx!

This is multiple questions packed into one question,

First why did this work

import elasticSVG from 'elastic-svg';

while this did not work

import * as elasticSVG from 'elastic-svg';

is because you are exporting a default export, a default export can be imported by any name so, the following will also work

import elasticSVGMYSepcialName from 'elastic-svg';

on the other hand

import * as elasticSVG from 'elastic-svg';

means import all named exports from this module under the name elasticSVG, in your case you are not exporting any named variable, so this wont work.

Now if you wish for webpack to directly inject your function into the window, you need to add libraryExport to your output object in webpack

output: {
    path: path.resolve(process.cwd(), "./dist"),
    filename: 'elasticSVG.js',
    library: 'elasticSVG',
    libraryTarget: 'umd',
    libraryExport: "default"
  },

libraryExport will configure which module will be exposed by Your library (elasticSVG) from your entry point module/namespace ( your ./index.js file).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM