Y
Y
youngmysteriouslight2021-05-06 16:56:23
JavaScript
youngmysteriouslight, 2021-05-06 16:56:23

Why is a module compiled by webpack returning a number when Code Split?

Q: When I try to split a package into multiple assembly modules that consist of some source code modules, the module starts returning a number.

Minimal example:

// package.json
{
  "name": "project",
  "version": "1.0.0",
  "main": "dist/all.js",
  "files": "dist/*.js",
  "devDependencies": {
    "webpack": "^5.36.2",
    "webpack-cli": "^4.7.0"
  }
}

/* СОДЕРЖАТЕЛЬНЫЕ МОДУЛИ */
// src/a.js
export default 'a'

// src/b.js
import a from './a';
export default 'b' + a;

// src/c.js
import a from './a';
export default 'c' + a;

/* ГРУППИРОВКА МОДУЛЕЙ */
// src/core.js
export { default as a } from './a';
export { default as b } from './b'

// src/ext.js
export { default as c } from './c'

// src/all.js
export { default as a } from './a'; // альтернативно: переимпорт из core.js
export { default as b } from './b';
export { default as c } from './c'; // альтернативно: переимпорт из ext.js

// webpack.config.js
const path = require('path');
let config = {
  mode: 'production',
  target: 'web',
  entry: {
    all: {
      import: './src/all.js',
    },
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    library: 'lambda',
    libraryTarget: 'umd',
    globalObject: 'this',
    umdNamedDefine: true
  },
};
module.exports = config;

// webpack2.config.js
const path = require('path');
let config = {
  mode: 'production',
  target: 'web',
  entry: {
    core: './src/core.js',
    all: {
      import: './src/all.js',
      dependOn: 'core',
    },
    ext: {
      import: './src/ext.js',
      dependOn: 'core',
    },
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    library: 'lambda',
    libraryTarget: 'umd',
    globalObject: 'this',
    umdNamedDefine: true
  },
};
module.exports = config;

We launch:
$ npx webpack
[...]
$ node -e 'console.log(require("./dist/all"))'
Object [Module] { a: [Getter], b: [Getter], c: [Getter] }
$ npx webpack --config webpack2.config.js 
[...]
$ node -e 'console.log(require("./dist/all"))'
1

Why, in the second case, does the module export a number, and not what it is supposed to export?

UPD . Through experiments, it was revealed that node distinguishes the way the module is connected.
Consider the example above. First we do npx webpack --config webpack2.config.js, then we go into node -iand act according to one of two scenarios:
1. first we call ./dist/core, then ./dist/all.
> require('./dist/core')
Object [Module] { a: [Getter], b: [Getter] }
> console.log(require('./dist/all'))
Object [Module] { a: [Getter], b: [Getter], c: [Getter] }

2. immediately call ./dist/all.
> require('./dist/all')
1

(between the options you need to exit the node)

As you can see, the method works if you load the dependency module before loading the dependent module.
For loading via browser <script>, when you need to unload modules into global variables, this is expected, but I expected the node to figure out in the second case to load the dist/core dependency.

What else I tried:
* replace target with 'node'
* different output.libraryTarget ('commonjs', 'commonjs2')
Same result.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Y
youngmysteriouslight, 2021-05-08
@youngmysteriouslight

Solved my problem. True, I had to switch to rollup.

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
  external: [/node_modules/],
  input: {
    core: 'src/core',
    all: 'src/all',
  },
  output: {
    dir: 'dist',
    format: 'cjs',
    entryFileNames: '[name].js',
  },
  plugins: [commonjs(), nodeResolve()],
};

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question