browserify-shim Sortable global не распознается react-sortable-mixin

У меня проблема, когда react-sortable-mixin не соблюдает объявление browserify-shim global:Sortable в моем файле package.json, что приводит к тому, что модуль Sortable упаковывается в мой пакет. Я столкнулся с аналогичной проблемой с другими модулями, так что это вполне может быть проблема с конфигурацией с моей стороны. Я создал небольшой тестовый пакет, который просто требует React и react-sortbable-mixin, чтобы продемонстрировать проблему:

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "Just a test",
  "main": "index.js",
  "dependencies": {
    "react": "^0.14.8",
    "sortablejs": "^1.4.2"
  },
  "devDependencies": {
    "browserify-shim": "^3.8.12"
  },
  "browserify": {
      "transform": [
          "browserify-shim"
      ]
  },
  "browserify-shim": {
    "react": "global:React",
    "sortablejs": "global:Sortable",
    "sortablejs/react-sortable-mixin": {
      "depends": "sortablejs:Sortable"
    }
  }
}

index.js

"use strict";
var React = require('react');
var SortableMixin = require('sortablejs/react-sortable-mixin');

react-sortable-mixin.js (только первая часть модуля...)

(function (factory) {
'use strict';

if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
    module.exports = factory(require('./Sortable'));
}
else if (typeof define === 'function' && define.amd) {
    define(['./Sortable'], factory);
}
else {
    /* jshint sub:true */
    window['SortableMixin'] = factory(Sortable);
}
})(function (/** Sortable */Sortable) { ...

Вот диагностический вывод от browserify:

% BROWSERIFYSHIM_DIAGNOSTICS=1 browserify index.js -t browserify-shim -o bundle.js

{ file: '/home/jlafosse/test/index.js',
  info: 
   { package_json: '/home/jlafosse/test/package.json',
     packageDir: '/home/jlafosse/test',
     shim: undefined,
     exposeGlobals: { react: 'React', sortablejs: 'Sortable' },
     browser: undefined,
     'browserify-shim': 
      { react: 'global:React',
        sortablejs: 'global:Sortable',
        'sortablejs/react-sortable-mixin': { depends: 'sortablejs:Sortable' } },
     dependencies: { react: '^0.14.8', sortablejs: '^1.4.2' } },
  messages: 
   [ 'Resolved "sortablejs/react-sortable-mixin" found in package.json to "/home/jlafosse/test/sortablejs/react-sortable-mixin"',
     'Found depends "sortablejs" as an installed dependency of the package',
     { resolved: 
        { '/home/jlafosse/test/sortablejs/react-sortable-mixin': 
           { exports: null,
             depends: { sortablejs: 'Sortable' } } } } ] }

{ file: '/home/jlafosse/test/index.js',
  info: 
   { package_json: '/home/jlafosse/test/package.json',
     packageDir: '/home/jlafosse/test',
     resolvedPreviously: true,
     shim: undefined,
     exposeGlobals: { react: 'React', sortablejs: 'Sortable' },
     browser: undefined,
     'browserify-shim': 
      { react: 'global:React',
        sortablejs: 'global:Sortable',
        'sortablejs/react-sortable-mixin': { depends: 'sortablejs:Sortable' } },
     dependencies: { react: '^0.14.8', sortablejs: '^1.4.2' } },
  messages: [] }

Я знаю, что глобальное шиммирование работает, потому что React не включен в комплект... однако, как упоминалось выше, Sortable включен. Кроме того, если я просто требую ('sortablejs') вместо sortablejs/react-sortable-mixin в моем файле index.js, Sortable НЕ БУДЕТ включен в пакет, как ожидалось, поэтому я думаю, что либо моя конфигурация неверна, либо модуль формат для react-sortable-mixin не учитывает браузерную оболочку.

Любая помощь приветствуется.


person Athan    schedule 01.04.2016    source источник
comment
Доступна ли ваша библиотека Sortable по всему миру, т. е. с тегом script? Не имеет смысла использовать как global:Sortable, так и ./node_modules/sortablejs/Sortable.js:Sortable в одном и том же файле package.json.   -  person YPCrumble    schedule 01.04.2016
comment
@YPCrumble - Да, я включаю Sortable CDN на стороне браузера/клиента. Сначала я пытался сделать: sortablejs/react-sortable-mixin: {depends: Sortable}, так как я понял, что это сообщит ему ссылку на глобальный Sortable ,,, но это тоже не сработало.   -  person Athan    schedule 01.04.2016
comment
Я предполагаю, что вы указали директиву browserify shim transform? Он отсутствует в вашем примере package.json.   -  person YPCrumble    schedule 01.04.2016
comment
@YPCrumble - Да, это есть в моем исходном коде, но почему-то упущено в примере. Я обновил пример, чтобы отразить это. Я также обновил директиву depend в примере.   -  person Athan    schedule 01.04.2016


Ответы (1)


Это невозможно без изменения содержимого библиотеки Sortable. Browserify Shim изменяет ваш файл bundle.js, чтобы включить либо window.PackageName, либо весь пакет, в зависимости от директивы browserify-shim в файле package.json.

В вашей ситуации, когда вы require('sortablejs/react-sortable-mixin'); ожидаете, что Browserify Shim изменит содержимое файла node_modules/sortablejs/react-sortable-mixin.js таким образом, что require('./Sortable') станет window.Sortable внутри этого файла. Проблема в том, что Browserify Shim не изменяет содержимое каталога node_modules, поэтому это невозможно.

Есть несколько вариантов:

  1. Вместо того, чтобы загружать Sortable через CDN, загрузите его глобально через скрипт bundle.js, чтобы убедиться, что он загружается только один раз. Ваш index.js изменится на:

    window.Sortable = require('sortablejs');
    var SortableMixin = require('sortablejs/react-sortable-mixin');
    
  2. Разветвите свой собственный автономный файл для react-sortable-mixin.js и вложите его прямо в свой пакет, чтобы Browserify Shim мог с ним работать.

person YPCrumble    schedule 01.04.2016
comment
Спасибо за объяснение. Что касается варианта № 1, это по-прежнему добавляет библиотеку Sortable в окончательный файл bundle.js .... это предполагаемое поведение? Что касается варианта 2, я думал об этом, но обычно предпочитаю избегать разветвления поддерживаемых библиотек. - person Athan; 01.04.2016
comment
@Athan yes - на самом деле предложение состоит в том, чтобы поместить библиотеку в свой файл bundle.js и загрузить ее таким образом вместо использования CDN. Я предполагаю, что вам нужна переменная, доступная глобально как Sortable, как если бы она была загружена через CDN, поэтому я включил window.Sortable. Если вам не нужно, чтобы она была доступна для других частей вашего кода в качестве переменной в объекте window, вы можете изменить эту строку на просто require('sortablejs');. - person YPCrumble; 01.04.2016
comment
Хорошо, спасибо. Что касается варианта 2, я провел быстрый тест, скопировав react-sortable-mixin.js из node_modules и потребовав локальную копию, однако я все равно получаю тот же результат, когда Sortable объединяется... - person Athan; 01.04.2016
comment
Обновление SortableJS 1.10+: window.Sortable = require('sortablejs').Sortable; - person Mário Valney; 26.02.2020