我一直在寻找解决这个问题的方法,但到目前为止还没有运气 - 甚至使用awesome gist about better local require paths并阅读并重新阅读了Avoiding ../../../../..上的Browserify手册的条目,我似乎无法为这个问题找到一个有效的解决方案。
我有一个用Browserify构建的库,我正在尝试发布到npm,如果你想测试我在这里描述的内容,你可以find for yourself。问题是:我想将其发布到NPM而不使用require()
调用中的相对路径,这就是我在使用Browserify时的工作方式。
请参阅使用Browserify的opts.paths
我可以更改require()
之类的内容
var Classy$Base = require('./base')
// and in another file
var Classy$Module = require('../../module')
到
var Classy$Base = require('classy/base')
// and in another file
var Classy$Module = require('classy/module')
哪个好极了!而且效果很棒!当我gulp bundle
我恢复工作classy.bundle.js
时,生活就会好起来。
那么我npm link
和另一个项目(也使用Browserify),npm link classy-js
,没有任何作用。我从require('classy-js')
内部收到错误,说“无法从'node_modules / classy-js / src ...'中找到模块'classy / base'等等。”
我希望能够创建一个我可以require('classy-js')
和require('classy-js/classy/module')
的库,并且可以访问库中所有其他有用的子模块,而不会牺牲库中的非相对路径自己的代码。
有没有办法可以做到这一点?
我尝试使用app-module-path但在使用时出现了Browserify错误,我尝试使用require-root来获得类似结果。
我也尝试过符号链接,并添加了一个npm postInstall脚本来自动生成符号链接,但也无济于事。
看起来这真的不应该那么难......
答案 0 :(得分:0)
嗯,它可能不受欢迎,我不确定我是否已经在npm上看到过这样做的包,但我认为这样可行:
// Name of module. I.e. same value as the `name` prop in `package.json`.
var Classy$Base = require('classy-js/base')
// and in another file
var Classy$Module = require('classy-js/module')
回复:这部分:
那么我
npm link
和另一个项目(也使用Browserify),npm link classy-js
,没有任何作用。
为了使这项工作与第一个建议一起使用,npm link
classy-js
自身(几乎)。假设你有/somedir/subdir/classy-js
。确保有/somedir/subdir/node_modules
,然后导航到/somedir/subdir
和npm link classy-js
。请确保您没有来自/somedir/subdir/classy-js/node_modules
的{{1}}和npm link
,否则您将获得一个循环引用,以免搞砸模块解析。
答案 1 :(得分:0)
在我看来,我已经解决了这个问题,虽然答案真的很愚蠢。虽然JMM's answer可能有效,但我没有采取这种方式。
由于两个项目都在使用Browserify,我只需要通过执行require('classy-js')
就可以在第二个项目中使用classy,并且它知道查看node_modules并找到它。但是,由于Browserify没有使用它在构建Classy捆绑时所做的opts.paths
,因此它不知道如何解析require('classy/base')
之类的路径。有了这个,我们就会收到一堆错误。
解决方案是一个npm postinstall
脚本,它创建一个空的node_modules文件夹(Classy没有依赖项,只有devDependencies),符号链接node_modules/classy
到src/classy
和node_modules/selfish
(另一个顶层) src /中的-level模块到src/selfish
。这样我们就不会混淆单独项目的opts.paths
,我们更好的require()
也会在节点中运行。
postinstall看起来像这样:
// package.json
...
"scripts": {
"test": "gulp test",
"postinstall": "mkdir node_modules && node create-symlinks.js"
},
...
和create-symlinks.js
看起来像
// create-symlinks.js
var fs = require('fs')
var c = '../src/classy'
, s = '../src/selfish'
, cd = 'node_modules/classy'
, sd = 'node_modules/selfish'
, e = undefined
e = fs.existsSync(cd);
if (!e) {
console.log('link', cd, 'to', c)
fs.symlinkSync(c, cd, 'dir')
}
e = fs.existsSync(sd)
if (!e) {
console.log('link', sd, 'to', s)
fs.symlinkSync(s, sd, 'dir')
}
它感觉到hack-y和错误,但是它起作用并且它使用了与"更好的本地需求"中给出的符号链接建议类似的约定。要旨。就是这样。
在Classy中访问子模块时,只需将任何公共API子模块(如Classy $ Module)公开为顶级Classy对象的字段,就更容易了(读:可能)。所以现在而不是做
var Classy$Module = require('classy-js/module')
或类似的东西,它只是
var Classy$Module = require('classy-js').Module
虽然不完全理想,但仍然有效,并且足够好。"