Подтвердить что ты не робот

Как мне() использовать консоль с помощью webpack?

Как мне (или) импортировать модули из консоли? Например, скажем, что я установил ImmutableJS npm, я хотел бы иметь возможность использовать функции из модуля, пока я работаю в консоли.

4b9b3361

Ответ 1

Включение этого в модуль позволит require([modules], function) использоваться из браузера

window['require'] = function(modules, callback) {
  var modulesToRequire = modules.forEach(function(module) {
    switch(module) {
      case 'immutable': return require('immutable');
      case 'jquery': return require('jquery');
    }
  })
  callback.apply(this, modulesToRequire);
}

Пример использования:

require(['jquery', 'immutable'], function($, immutable) {
  // immutable and $ are defined here
});

Примечание. Каждый параметр switch-statement должен либо быть тем, что этот модуль уже требует, либо предоставлен ProvidePlugin


Источники:

Основываясь на этом ответе, который можно использовать для добавления всей папки.

Альтернативный метод от Документы в Интернете - что позволяет что-то вроде require.yourModule.function()

Ответ 2

Вот еще один общий способ сделать это.

Требуется модуль по идентификатору

Текущая версия WebPack предоставляет webpackJsonp(...), которая может использоваться для запроса модуля по идентификатору:

function _requireById(id) {
  return webpackJsonp([], null, [id]);
}

или в TypeScript

window['_requireById'] =
  (id: number): any => window['webpackJsonp'];([], null, [id]);

Идентификатор отображается в верхней части модуля в комплекте или в нижнем колонтитуле исходного исходного файла, который подается через исходные карты.

Требуется модуль по имени

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

/**
 * Returns a promise that resolves to the result of a case-sensitive search
 * for a module or one of its exports. `makeGlobal` can be set to true
 * or to the name of the window property it should be saved as.
 * Example usage:
 *   _requireByName('jQuery', '$');
 *   _requireByName('Observable', true)´;
 */
window['_requireByName'] =
  (name: string, makeGlobal?: (string|boolean)): Promise<any> =>
    getAllModules()
    .then((modules) => {
      let returnMember;
      let module = _.find<any, any>(modules, (module) => {
        if (_.isObject(module.exports) && name in module.exports) {
          returnMember = true;
          return true;
        } else if (_.isFunction(module.exports) &&
                   module.exports.name === name) {
          return true;
        }
      });
      if (module) {
        module = returnMember ? module.exports[name] : module.exports;
        if (makeGlobal) {
          const moduleName = makeGlobal === true ? name : makeGlobal as string;
          window[moduleName] = module;
          console.log(`Module or module export saved as 'window.${moduleName}':`,
            module);
        } else {
          console.log(`Module or module export 'name' found:`, module);
        }
        return module;
      }
      console.warn(`Module or module export '${name}'' could not be found`);
      return null;
    });

// Returns promise that resolves to all installed modules
function getAllModules() {
  return new Promise((resolve) => {
    const id = _.uniqueId('fakeModule_');
    window['webpackJsonp'](
      [],
      {[id]: function(module, exports, __webpack_require__) {
        resolve(__webpack_require__.c);
      }},
      [id]
    );
  });
}

Это быстрый выстрел, поэтому все для улучшения!

Ответ 3

Возможность использования модулей require в консоли удобна для отладки и анализа кода. @psimyn ответ очень специфичен, поэтому вы вряд ли будете поддерживать эту функцию со всеми необходимыми модулями.

Когда для этой цели мне нужен один из моих собственных модулей, я присваиваю ему свойство window, поэтому я могу получить его, например, window.mymodule = whatever_im_exporting;. Я использую тот же трюк, чтобы выставить системный модуль, если я хочу играть с ним, например:

myservice.js:

let $ = require('jquery');
let myService = {};

// local functions service props etc...

module.exports = myService;

// todo: remove these window prop assignments when done playing in console
window.$ = $;
window.myService = myService;

Это по-прежнему немного больно, но, копаясь в связках, я не вижу возможности удобно отображать модули.

Ответ 4

После создания моего собственного пакета npm для этого (см. здесь), а также для поиска существующего (см. здесь), я также нашел способ сделать это в одной строке, просто используя встроенные функции webpack.

Он использует контексты WebPack: https://webpack.github.io/docs/context.html

Просто добавьте следующую строку в файл непосредственно в папку "Источник":

window.Require = require.context("./", true, /\.js$/);

Теперь вы можете использовать его (например, в консоли) следующим образом:

let MyComponent = Require("./Path/To/MyComponent");
console.log("Retrieved MyComponent: " + MyComponent);

Однако одним из важных недостатков этого подхода по сравнению с двумя упомянутыми выше решениями является то, что он, похоже, не работает для файлов в папке node_modules. Когда путь настроен на "../", веб-пакет не скомпилируется - по крайней мере, в моем проекте. (возможно, потому, что папка node_modules настолько массивна)

Ответ 5

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

require.ensure([], function () {
    window.require = function (module) {
        return require(module);
    };
});

Используйте консоль:

require("./app").doSomething();

Подробнее

Ответ 6

expose-loader - это, на мой взгляд, более элегантное решение:

require("expose-loader?libraryName!./file.js");
// Exposes the exports for file.js to the global context on property "libraryName".
// In web browsers, window.libraryName is then available.

Ответ 7

Я нашел способ, который работает, как для WebPack 1, так и для 2. (пока источник не ограничен)

Репо: https://github.com/Venryx/webpack-runtime-require

Установка

npm install --save webpack-runtime-require

Использование

Сначала требуется модуль хотя бы один раз.

import "webpack-runtime-require";

Затем он добавит функцию Require() к объекту window, для использования в консоли или в любом месте вашего кода.

Затем просто используйте его, например:

let React = Require("react");
console.log("Retrieved React.Component: " + React.Component);

Это не очень красиво (он использует регулярные выражения для поиска функций обертки модуля) или быстро (занимает ~ 50 мс первого вызова и ~ 0 мс после), но оба они отлично подходят, если это просто для проверки хака в консоли.

Техника

Ниже приведена обрезанная версия источника, чтобы показать, как она работает. (см. репо для полного/последнего)

var WebpackData;
webpackJsonp([],
    {123456: function(module, exports, __webpack_require__) {
        WebpackData = __webpack_require__;
    }},
    [123456]
);

var allModulesText;
var moduleIDs = {};
function GetIDForModule(name) {
    if (allModulesText == null) {
        let moduleWrapperFuncs = Object.keys(WebpackData.m).map(moduleID=>WebpackData.m[moduleID]);
        allModulesText = moduleWrapperFuncs.map(a=>a.toString()).join("\n\n\n");

        // these are examples of before and after webpack transformation: (which the regex below finds the var-name of)
        //      require("react-redux-firebase") => var _reactReduxFirebase = __webpack_require__(100);
        //      require("./Source/MyComponent") => var _MyComponent = __webpack_require__(200);
        let regex = /var ([a-zA-Z_]+) = __webpack_require__\(([0-9]+)\)/g;
        let matches = [];
        let match;
        while (match = regex.exec(allModulesText))
            matches.push(match);

        for (let [_, varName, id] of matches) {
            // these are examples of before and after the below regex transformation:
            //      _reactReduxFirebase => react-redux-firebase
            //      _MyComponent => my-component
            //      _MyComponent_New => my-component-new
            //      _JSONHelper => json-helper
            let moduleName = varName
                .replace(/^_/g, "") // remove starting "_"
                .replace(new RegExp( // convert chars where:
                          "([^_])"      // is preceded by a non-underscore char
                        + "[A-Z]"       // is a capital-letter
                        + "([^A-Z_])",  // is followed by a non-capital-letter, non-underscore char
                    "g"),
                    str=>str[0] + "-" + str[1] + str[2] // to: "-" + char
                )
                .replace(/_/g, "-") // convert all "_" to "-"
                .toLowerCase(); // convert all letters to lowercase
            moduleIDs[moduleName] = parseInt(id);
        }
    }
    return moduleIDs[name];
}

function Require(name) {
    let id = GetIDForModule(name);
    return WebpackData.c[id].exports;
}

Ответ 8

После создания модуля npm для этого (см. мой другой ответ), я выполнил поиск на npms.io и, похоже, нашел существующий доступный веб-пакет для этой цели.

Репо: https://www.npmjs.com/package/webpack-expose-require-plugin

Установка

npm install --save webpack-expose-require-plugin

Использование

Добавьте плагин в конфигурацию webpack, а затем используйте во время выполнения следующим образом:

let MyComponent = require.main("./path/to/MyComponent");
console.log("Retrieved MyComponent: " + MyComponent);

Подробнее см. страницу с информацией о пакете/репо.

ИЗМЕНИТЬ

Я попробовал плагин в своем собственном проекте, но не смог заставить его работать; Я продолжал получать ошибку: Cannot read property 'resource' of undefined. Я останусь здесь, если это сработает для других людей. (В настоящее время я использую решение, упомянутое выше)

Ответ 9

Добавление приведенного ниже кода к одному из ваших модулей позволит вам загружать модули по id.

window.require = __webpack_require__;

В консоли используйте следующее:

require(34)