youngmysteriouslight
@youngmysteriouslight
ТК, ТТ, JS, FP, WM

Почему модуль, собранный webpack, возвращает число при Code Split?

Вопрос: когда я пытаюсь разбить пакет на несколько модулей-сборок, которые состоят из некоторых модулей исходного кода, модуль начинает возвращать число.

Минимальный пример:
// 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;

Запускаем:
$ 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

Почему во втором случае модуль экспортирует число, а не то, что ему положено экспортировать?

UPD. Путём экспериментов было выявлено, что node различает способ подключения модуля.
Рассмотрим пример выше. Сначала делаемnpx webpack --config webpack2.config.js, затем заходим в node -i и действуем по одному из двух сценариев:
1. сначала вызываем ./dist/core, затем ./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. сразу вызываем ./dist/all.
> require('./dist/all')
1

(между вариантами необходимо выйти из ноды)

Как видно, метод работает, если перед загрузкой зависимого модуля загрузить модуль-зависимость.
Для загрузки через <script> браузера, когда нужно в глобальные переменные выгрузить модули, это ожидаемо, но от ноды я ожидал, что она сама сообразит во втором случае подгрузить зависимость dist/core.

Что ещё я пробовал:
* заменить target на 'node'
* разные output.libraryTarget ('commonjs', 'commonjs2')
Результат тот же.
  • Вопрос задан
  • 59 просмотров
Пригласить эксперта
Ответы на вопрос 1
youngmysteriouslight
@youngmysteriouslight Автор вопроса
ТК, ТТ, JS, FP, WM
Решил свою проблему. Правда, пришлось перейти на 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()],
};
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы