1. 困ったこと
「browserifyのrequireに指定できるのは文字列リテラルだけ」を参照
2. 結論
browserifyのtransformであるaliasifyのreplacements(正規表現置換)を使用
3. やったこと
3-1. aliasifyインストール
3-1-1. package.jsonのdevDependenciesにaliasifyを追記
package.json
"aliasify": "",
3-1-2. npmでインストール
npm install --save-dev
3-2. Gruntfile.jsのbrowserifyのところにoptionsを追記
Gruntfile.js
browserify: {
options: {
transform: [
[
'aliasify', {
replacements: {
// Gruntfile.jsからの相対パスを指定
// 直下のサブディレクトリは「./」から記述
'%UTIL%': './xxx/util/',
'%UTIL2%': '../proj2/xxx/util/'
}
}
]
]
},
dist: {
files: {
'./yyy/bundle.js': './zzz/parent.js'
}
}
}
3-3. ソースのrequireを書換
zzz/parent.js
var a = require('%UTIL%/a'); // 以前は../xxx/util/a
var b = require('%UTIL%/b');
var c = require('%UTIL2%/c'); // 以前は../../proj2/xxx/util/c
var d = require('%UTIL2%/d');
var child = require('./sub/child');
zzz/sub/child.js
var a = require('%UTIL%/a'); // 以前は../../xxx/util/a
var c = require('%UTIL2%/c'); // 以前は../../../proj2/xxx/util/c
3-4. grunt実行
grunt
3-5. 結果
yyy/bundle.jsのzzz/parent.jsのあたり↓
yyy/bundle.js
var a = require('./../xxx/util/a'); // 以前は../xxx/util/a
var b = require('./../xxx/util/b');
var c = require('./../../proj2/xxx/util/c'); // 以前は../../proj2/xxx/util/c
var d = require('./../../proj2/xxx/util/d');
var child = require('./sub/child');
yyy/bundle.jsのzzz/sub/child.jsのあたり↓
yyy/bundle.js
var a = require('./../../xxx/util/a'); // 以前は../../xxx/util/a
var c = require('./../../../proj2/xxx/util/c'); // 以前は../../../proj2/xxx/util/c
置換設定はGruntfile.jsからの相対パスだったが、置換結果はrequire元jsからの相対パスとなっている
3-6. IntelliSense対応
当たり前だがrequire('%UTIL%/a')
なんて書いたらVSCodeのIntelliSenseが効かなくなる
そもそもIntelliSenseもrequireに変数や文字列連結を使うとダメ
なので以下のようにjsconfig.jsonを書いてVSCodeで開くフォルダに置いた
(pathsの右辺にはjsconfig.jsonからの相対パスを書く)
jsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"%UTIL%/*": ["proj1/xxx/util/*"],
"%UTIL2%/*": ["proj2/xxx/util/*"]
}
}
}
おまけ1. 置換じゃなくてrequireのrootを指定するやり方
多分、以下みたいな感じで行けるのではないかと(未確認)
zzz/parent.js
var a = require('a'); // 以前は../xxx/util/a
var b = require('b');
var c = require('c'); // 以前は../../proj2/xxx/util/c
var d = require('d');
var child = require('./sub/child');
zzz/sub/child.js
var a = require('a'); // 以前は../../xxx/util/a
var c = require('c'); // 以前は../../../proj2/xxx/util/c
Gruntfile.js
browserify: {
options : {
browserifyOptions : {
// requireに「./」「../」以外から始まるパスを指定した場合に以下から探す
// (Gruntfile.jsからの相対パス)
paths: ['./xxx/util/', '../proj2/xxx/util/']
}
},
dist: {
files: {
'./yyy/bundle.js': './zzz/parent.js'
}
}
}
jsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"*": ["proj1/xxx/util/*", "proj2/xxx/util/*"]
}
}
}
おまけ2. sass
こんな感じで行けてたような記憶
scss/style.scss
@import "a"; // 以前は../proj2/scss/a
Gruntfile.js
sass : {
options : {
loadPath: ['../proj2/scss/']
},
ddist : {
files : {
'./yyy/css/style.css' : './scss/style.scss'
}
}
},