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

Как мне управлять относительным сглаживанием путей в нескольких пулах для руткинга?

Это немного, но мне нужен пример кода, чтобы проиллюстрировать мое замешательство. После этого меня интересует ответ на следующее:

  • Как использовать require('module') вместо require('../../src/module') или require('./module')?
  • Как повторно использовать ./index.js в spec/specs.js без дублирования работы? (И предотвращение запуска src/app.js как модуля ввода).

Я уже начал несколько проектов на основе браузера и люблю browserify и хрюкать. Но каждый проект умирает в той же точке моей кривой развития/обучения. Как только я добавлю тестирование в микс и вы должны управлять двумя browserify пакетами (app.js и spec/specs.js), вся система разваливается. Я объясню:

Я использую grunt-browserify и задаю свой начальный каталог:

.
├── Gruntfile.js
├── index.js  (generated via grunt-browserify)      [1]
├── lib
│   ├── jquery
│   │   └── jquery.js                               [2]
│   └── jquery-ui
│       └── jquery-ui.js                            [3]
├── spec
│   ├── specs.js  (generated via grunt-browserify)  [4]
│   └── src
│       ├── spec_helper.js  (entry)
│       └── module_spec.js  (entry)
└── src
    ├── app.js  (entry)
    └── module.js
  • Использует один файл записи (src/app.js) и выполняет код для объединения всех необходимых модулей.
  • Использует прокси-браузер для псевдонима jquery.
  • Просто накладывается на jquery-ui без прокладки (требуется после вас var $ = require('jquery')).
  • Использует все вспомогательные и специальные файлы в spec/src в качестве модулей ввода.

Я перейду через свою конфигурацию:

browserify: {
  dist: {
    files: {
      'index.js': ['src/app.js']
    }
  }
}

// in app.js
var MyModule = require('./module'); // <-- relative path required?!

С

Теперь добавьте jquery:

browserify: {
  options: {
    shim: {
      jquery: {
        path: 'lib/jquery/jquery.js',
        exports: '$'
      }
    },
    noParse: ['lib/**/*.js'],
    alias: [
      'lib/jquery-ui/jquery-ui.js:jquery-ui'
    ]
  },
  dist: {
    files: {
      'index.js': ['src/app.js']
    }
  }
}

// in app.js
var $ = require('jquery');
require('jquery-ui');
var MyModule = require('./module');

С

Теперь добавьте спецификации:

options: {
  shim: {
    jquery: {
      path: 'lib/jquery/jquery.js',
      exports: '$'
    }
  },
  noParse: ['lib/**/*.js'],
  alias: [
    'lib/jquery-ui/jquery-ui.js:jquery-ui'
  ]
},
dist: {
  files: {
    'app.js': 'src/app.js'
  }
},
spec: {
  files: {
    'spec/specs.js': ['spec/src/**/*helper.js', 'spec/src/**/*spec.js']
  }
}

// in app.js
var $ = require('jquery');
require('jquery-ui');
var MyModule = require('./module');

// in spec/src/module_spec.js
describe("MyModule", function() {
  var MyModule = require('../../src/module'); // <-- This looks like butt!!!
});

Сад

Подводя итог: Как мне...

  • Используйте require('module') вместо require('../../src/module') или require('./module')?
  • повторно использовать ./index.js в spec/specs.js без дублирования работы? (И предотвращение запуска src/app.js как модуля ввода).
4b9b3361

Ответ 1

Эти ответы зависят от того, как настраивается остальная часть вашего проекта, но, возможно, это хорошая отправная точка. Кроме того, вам нужно будет использовать текущую версию v2 beta grunt-browserify для этого, чтобы на самом деле работать (npm install [email protected]).

1.

Вы можете использовать aliasMapping для создания динамических псевдонимов для своих модулей. Просто для ясности, переместите все ваши модули на src/modules/. Тогда конфигурация aliasMapping может быть примерно такой:

options: {
  aliasMappings: {
    cwd: 'src',
    src: ['modules/**/*.js']
  }
}

Предположим, что у вас есть модуль в src/modules/magic/stuff.js, тогда вы можете потребовать его так, независимо от того, где находится файл .js, который выполняет запрос:

var magicStuff = require('modules/magic/stuff.js');

2.

Не уверен в этом. Структура вашего проекта показывает spec/index.js, но вы указываете spec/specs.js. Должны ли они быть одним и тем же файлом?

В любом случае, о какой дублирующей работе вы говорите? Поскольку ./index.js имеет другой файл записи, чем spec/index.js. Если вы ищете способ включить ./index.js в specs/, то, возможно, вы можете скопировать его перед запуском тестов, а не создавать его с нуля.

Ответ 2

Простой ответ:

Простейшим является использование опции paths для браузера. Я использую его в течение нескольких месяцев с большим успехом. Я даже сделал стартовый комплект, который использует эту функцию: https://github.com/stample/gulp-browserify-react-phonegap-starter

var b = browserify('./app', {paths: ['./node_modules','./src/js']});

paths - массив require.paths, если ничего не найдено в обычном node_modules рекурсивная прогулка

Если у вас есть файл в src/js/modulePath/myModule.js, это не позволит вам писать require("myModule") всюду, а скорее require("modulePath/myModule"), из любого из ваших других исходных файлов.

Устаревшая опция?

Это не похоже!

Алгоритм разрешения модуля Browserify отражает алгоритм разрешения в NodeJS. Таким образом, опция paths Browserify является зеркалом поведения переменной NODE_PATH env для NodeJS. Заявитель Browserify (substack) утверждает в этой теме SO, что параметр NODE_PATH устарел в NodeJS, и поэтому он также устарел в Browserify и может быть удален в следующих версиях.

Я не согласен с этим утверждением.

См. документацию NODE_PATH. Не упоминается, что опция устарела. Однако есть еще интересное упоминание о том, что делает в сторону требования к подставке:

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

И этот вопрос был опубликован в 2012 году в списке рассылки.

Oliver Leics: is NODE_PATH deprecated? 
Ben Noordhuis (ex core NodeJS contributor): No. Why do you ask? 

И если что-то не устранено в алгоритме разрешения NodeJS, я не думаю, что он будет удален в ближайшее время из Browserify:)

Заключение

Вы можете использовать опцию paths или поместить свой код в node_modules, как официальная документация, и Рекомендовать обозреватель.

Лично мне не нравится идея поместить мой собственный код в node_modules, поскольку я просто держу всю эту папку вне моего исходного элемента управления. Я использую параметр paths в течение нескольких месяцев и не имею никаких проблем, и моя скорость сборки довольно хороша.

Решение по размещению символической ссылки внутри node_modules может быть удобным, но, к сожалению, у нас есть разработчики, работающие с Windows здесь...

Я думаю, что там случай, когда вы не хотите использовать параметр paths: при разработке библиотеки, опубликованной в репозитории NPM, который потребуется другим приложениям. Вы действительно не хотите, чтобы эти клиенты библиотеки настраивали специальную конфигурацию сборки только потому, что вы хотели избежать относительного пути ад в своей библиотеке.

Другой возможный вариант - использовать remapify

Ответ 3

Все ответы здесь, касающиеся псевдонимов и opts.paths/$NODE_PATH, невелики, потому что этот подход является устаревшей частью модульной системы в node и браузером, поэтому он может перестать работать в любое время.

Вы должны изучить как работает алгоритм node_modules, чтобы вы могли эффективно организовать свой код таким образом, чтобы он хорошо работал с вложенными node_modules каталоги.

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

  • Поместите свой внутренний модульный код в node_modules/ или node_modules/app, чтобы вы могли require('yourmodule') или require('app/yourmodule') в зависимости от того, какой вы предпочитаете.
  • Вы можете использовать символическую ссылку, если вы разрабатываете не-windows-платформы, и это то, что вы предпочитаете.

Не используйте opts.path/$NODE_PATH. Это делает ваш проект:

  • неявно зависят от неочевидной настройки конфигурации или среды
  • сложнее сделать работу как в node, так и в браузере
  • уязвим для изменений в модульной системе, поскольку пути массивов устарели в node и браузерируют

Ответ 4

Я думаю, что самый лучший способ пойти - это, как отмечает Себастьян Лорбер, с установкой пути в вашем вызове браузера через трубу.

Но с последней версией браузера (с этого момента, то есть [email protected]) переменная пути хранит пути только, которые Browserify будет использовать для своего процесса. Насколько я могу сказать, установка переменной paths исключает, скажем... ваши глобальные папки для node. В результате вам понадобится задача Gulp, которая выглядит примерно так:

gulp.task('reactBuild', function() {
  return gulp.src(newThemeJSX)
    .pipe(browserify({
        debug: true,
        extensions: ['.jsx', '.js', '.json'],
        transform: [reactify],
        paths: ['../base_folder/node_modules', '/usr/lib/node_modules']
    }))
    .pipe(gulp.dest(newThemeBuilt))
    .on('error', function(error) {
        console.log(error);
    });
});