如何在多个grunt-browserify包中pipe理相对path别名?
这是很长的,但我需要代码示例来说明我的困惑。 之后我有兴趣回答以下几点:
- 如何使用
require('module')
而不是require('../../src/module')
或require('./module')
? - 如何在
spec/specs.js
重复使用spec/specs.js
而不重复工作? (并防止src/app.js
运行,因为它是一个入口模块)。
我已经开始了几个基于浏览器的项目,并且喜欢browserify和grunt。 但是,每个项目都在我的开发/学习曲线中死去。 一旦我将testing添加到组合中,并且必须pipe理两个spec/specs.js
包( 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
)并执行代码遍历所有需要的模块。 - 使用browserify-shim别名
jquery
。 - 只是别名
jquery-ui
没有垫片(需要你var $ = require('jquery')
)。 - 使用
spec/src
所有帮助器和spec文件作为input模块。
我将通过我的configuration:
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')
? - 在
spec/specs.js
重复使用./index.js
而不重复工作? (并防止src/app.js
运行,因为它是一个入口模块)。
这些答案取决于你的项目的其余部分是如何设置的,但也许这是一个很好的起点。 此外,您将需要使用grunt-browserify的当前v2 beta来实际工作( npm install grunt-browserify@2
)。
1。
您可以使用aliasMapping为您的模块创build一些dynamic别名。 为了清楚起见,我们把所有的模块移到src/modules/
。 然后,aliasMappingconfiguration可能是这样的:
options: { aliasMappings: { cwd: 'src', src: ['modules/**/*.js'] } }
让我们假设你在src/modules/magic/stuff.js
有一个模块,那么你可以这样要求它,而不pipe在做需求的.js文件的位置:
var magicStuff = require('modules/magic/stuff.js');
2。
不知道这个。 您的项目结构显示spec/index.js
,但您提到spec/specs.js
。 他们应该是同一个文件吗?
无论如何,你在说什么重复的工作? 因为./index.js
与spec/index.js
有不同的入口文件。 如果你正在寻找一种方法来在specs/
包含./index.js
,那么也许你可以在运行testing之前复制它,而不是从头开始构build它。
简单的回答:
最简单的是使用browserify的paths
选项。 我用了几个月,取得了巨大的成功。 我甚至做了一个使用这个function的入门工具包: https : //github.com/stample/gulp-browserify-react-phonegap-starter
var b = browserify('./app', {paths: ['./node_modules','./src/js']});
paths – 如果在正常的node_modulesrecursion步骤中找不到任何东西,则使用require.paths数组
如果你在src/js/modulePath/myModule.js
有一个文件,这不会让你在任何地方编写require("myModule")
,而是从你的其他源文件中require("modulePath/myModule")
。
已弃用的选项?
这似乎不是这样!
Browserify模块parsingalgorithm镜像NodeJS中的parsingalgorithm 。 Browserify的paths
选项因此是NODE_PATH
envvariables行为的镜像。 Browserify作者(substack)在本SO主题中声称NODE_PATH
选项在NODE_PATH
被弃用,因此在Browserify中也被弃用,并且可能在下一版本中被删除。
我不同意这个说法。
请参阅NODE_PATH文档。 没有提到该选项已被弃用。 然而,还是有一个有趣的提到,这是在suback的索赔方向:
强烈build议您将您的依赖项本地放置在node_modules文件夹中。 他们将被加载更快,更可靠。
而这个问题已经在2012年发布在邮件列表上。
Oliver Leics: is NODE_PATH deprecated? Ben Noordhuis (ex core NodeJS contributor): No. Why do you ask?
如果在NodeJSparsingalgorithm中没有删除某些内容,我认为它不会很快从Browserify中移除:)
结论
您可以使用paths
选项,也可以将代码放在node_modules
如官方文档和Browserify作者推荐的 。
就我个人而言,我不喜欢把自己的代码放在node_modules
因为我只是把这个文件夹放在我的源代码控制之外。 我现在使用paths
选项已经有几个月了,根本没有任何问题,而且我的构build速度也相当不错。
node_modules
在node_modules
里放一个符号链接的解决scheme可能很方便,但不幸的是我们有开发人员在这里使用Windows …
但是,我认为有些情况下,您不想使用paths
选项 :当您正在开发在其他应用程序需要的NPM存储库上发布的库时。 你真的不希望这些库客户端必须设置特殊的构buildconfiguration,只是因为你想避免在你的lib中的相对path地狱。
另一个可能的select是使用remapify
这里关于别名和opts.paths
/ $NODE_PATH
所有答案$NODE_PATH
是很好,因为这个方法在node和$NODE_PATH
中是模块系统的一个不推荐的部分,所以它可能随时停止工作。
您应该了解node_modulesalgorithm是如何工作的,这样您就可以用嵌套的node_modules
目录很好地组织代码。
在browserify手册中有一节介绍避免../../../../../../ ..相对path问题。 可以概括为:
- 把你的内部模块化代码放在
node_modules/
或node_modules/app
这样你就可以根据自己喜好selectrequire('yourmodule')
还是require('app/yourmodule')
。 - 如果您正在为非Windows平台开发,则可以使用符号链接,而这正是您所喜欢的。
不要使用opts.path
/ $NODE_PATH
。 它使你的项目:
- 隐含地依赖于非显而易见的configuration或环境设置
- 难以在节点和浏览器中工作
- 由于在节点和浏览器中不build议使用数组path,所以易受模块系统中的更改影响
正如Sebastien Lorber所指出的,我认为最好的方式就是在通过pipe道调用browserify的过程中设置path。
但是,使用browserify的最新版本(截至目前,这是browserify@11.0.0
),pathvariables存储了Browserify将用于其进程的唯一path。 所以设置pathvariables将排除说…您的节点的全局文件夹,据我所知。 因此,你需要一个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); }); });