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

Компилировать модуль npm в один файл без зависимостей

Я пытаюсь скомпилировать модуль uncss npm в один файл .js, который подходит для компиляции ExecJS. Например, у парня script этого. Целью является создание простой рубиновой обертки для нее, аналогичной ruby-coffee-script.

То, что я пробовал далеко:

  • Нашел ответ, который предложил UglifyJS. Нигде не было этого.
  • Используется браузер, который должен был сделать трюк, но он не может скомпилировать lib/uncss.js со следующим сообщением об ошибке:

    Error: ENOENT, open 'tls' while resolving "tls" from file /home/prajjwal/code/uncss/node_modules/request/node_modules/forever-agent/index.js
    

Я предполагаю, что это потому, что в браузере нет подходящей прокладки? Меня также беспокоят прокладки, которые браузеру заменяет модули node. Они полностью безопасны в использовании? Я собираюсь внедрить это в рубиновый камень. Не думайте, что обозреватель - это то, что я должен использовать. Есть ли другой способ создания отдельного .js из модуля npm?

Любая помощь была оценена.

4b9b3361

Ответ 1

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

Чтобы быть полным, вот версии используемых мной инструментов: Node v0.10.26 и browserify 3.38.0. Я не тестировал другую версию, поэтому у них могут быть проблемы.

Вот шаги, которые я предпринял после клонирования uncss:

  • npm install, который загружает и устанавливает правильные пакеты
  • Из-за какой-то проблемы с версиями с NPM мне пришлось вручную установить пакет graceful-fs (зависимость от одной из зависимостей uncss) из Github (он недоступен через npm)

    npm install https://github.com/isaacs/node-graceful-fs/tarball/v2.0.3
    
  • На этом этапе я запустил браузер. Оказывается, что browserify имеет флаг --bare, который выполняет пару действий:

    Псевдоним для --no-builtins, --no-commondir, и устанавливает --insert-глобальные вары     просто "__filename, __ dirname". Это удобно, если вы хотите запускать пакеты в      node.

    С этим флагом браузер не вводит свои собственные прокладки для основных модулей. Полную команду я использовал:

    browserify lib/uncss.js --bare > uncss.js
    

После выполнения выше, файл uncss.js содержит uncss вместе со своими связанными зависимостями. К сожалению, поскольку браузер оборачивает все, что находится внутри собственной функции require, теперь вложенные модули ничего не экспортируют изначально.

$ node
> require('./uncss')
{}
>

Чтобы исправить это, мне пришлось изменить начальную строку сгенерированного пакета из этого:

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

:

module.exports = (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require,ex;for(var o=0;o<r.length;o++)ex=s(r[o]);return ex})({1:[function(require,module,exports){

Примечание: это не только дополнение module.exports - там была и некоторая модификация в середине, которая была нужна также *.

После этого пакет, казалось, работал:

$ node
> require('./uncss')
[Function: init]
>

*: По сути, browserify определяет внутренний function s(o, u), который действует как require. Окружающий код запускается путем циклического перехода через то, что выглядит как список "основных модулей" (в данном случае только один), require, но не сохраняя результат. Затем он возвращает s, функцию require -like (почему, я не уверен) в качестве вывода всей анонимной функции. Все, что мне нужно было сделать, это добавить переменную для хранения результатов, а затем вместо нее return.

Ответ 2

В браузере есть флаг -standalone, который может помочь здесь.

В командной строке:

browserify -s moduleName --bare moduleName.js -o filename.js

В node script вы можете импортировать конкатенированный модуль:

var moduleName = require('./filename');

Однако вам все равно придется игнорировать и/или заглушать любые сложные модули.

Ответ 3

В то время как это не невозможно, это немного сложно, нет инструмента, который я знаю, чтобы сделать это автоматически, но его coulb можно выполнить вручную.

Итак, если вы загружаете модуль таким образом:

var async = require('async');

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

var global_async = null;

Затем включите код модуля внутри анонимной функции и замените "module.exports" на глобальный var, который вы указали ранее:

module.exports = async

С

global_async = async;

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

Если вы хотите создать драгоценный камень, создающий обертку вокруг "uncss", вы можете проверить, установлены ли node и uncss перед чем-либо, если нет, установите оба, а затем просто вызовите их, точно так же, как uncss делает с phantomjs.