2016-10-24 10 views
1

조건부로 require 모듈을 컴파일 할 때 런타임에 번들되기 때문에 browserify가있는 모듈을 사용할 수 없다는 것을 알고 있습니다. 조건부 스트립 모듈은 어떨까요?조건부 컴파일/require는 browserify (데드 코드 제거)를 사용합니다.

이미지 갤러리를 만들 수있는 앱이 있다고 가정 해 보겠습니다. 갤러리는 또한 편집 할 수 있습니다 (이미지 순서 변경 등). 그러나 갤러리의 렌더링과 편집은 결합되어 완전히 분리 될 수 없습니다. 그러나 갤러리를 배포하기 위해 편집 기능이 필요하지 않으며 어떤 모듈이 사용되는지 알고 있습니다. 두 가지 다른 번들을 만들고 싶습니다. 하나는 편집 기능이 있고 다른 하나는 편집 코드의 대부분을 제거하지 않고 만드는 것입니다. 내가 한 것은 envify과 uglify의 dead code 제거를 사용하여 더 작은 번들에서 내 코드를 제외시키는 것입니다.

전 (thing.js) (thing.js) 후

//...some code that only the editor needs... 
module.exports = thing; 

if(process.env.INCLUDE_EDITOR === 'yes') { 
    //...some code that only the editor needs... 
    module.exports = thing; 
} 

이 잘 작동하고 편집기 번들이 이미 작다. 그리고 나는 다른 번들이 결코 thing의 기능을 사용하지 않을 것이므로, 아무 것도 내보내지 않고 빈 모듈을 가지고도 괜찮습니다.

이제 문제가 있습니다. thing.js에 모듈이 필요하다면 (예 : pica), 불필요한 코드 제거 이후 아무도 사용하지 않아도 번들로 제공됩니다 ().

전 (thing.js) (thing.js) 후

var pica = require('pica'); 
//...some code that uses pica... 
module.exports = thing; 

if(process.env.INCLUDE_EDITOR === 'yes') { 
    var pica = require('pica'); 
    //...some code that uses pica... 
    module.exports = thing; 
} 

그것을 요약하면 : 내 번들은 이제 pica 라이브러리를 포함하고 있지만, 아무도 그것을 필요로하지 않습니다. 필요한 코드는 죽은 코드 였지만, uglify는 분명히 pica을 제거 할 수 있다는 것을 이해할 수 없습니다.

+0

아마도''factor-bundle' (https://github.com/substack/factor-bundle)이 유용할까요? – casr

+0

@casr 감사합니다! 나는 그것이 여기에 적용될 수 있다고 생각하지 않는다. 문서에서 예제를 보았을 때,'console.log (z (5) * w (2));가 절대 실행되지 않는다는 것을 알고 있기 때문에 번들 x에서 w와 z를 제거하는 것이 좋습니다. 그것은 여전히 ​​묶음에있을 것입니다. 나는 어리석은 미친 일을 여기에서하는 종류 다. 하지만 이봐, 나는 비 편집기 번들에서 20 %를 제거했다! – Prinzhorn

답변

1

변환을 위해 나는 당신이 후에있는 것은이 uglifyify 같은 변화라고 생각합니다. 이 조건이 필요 당신이 죽은 코드 경로를 제거 할 수 있습니다 의미하는 번들에 포함되기 전에 Uglifyify 당신에게 추하게의 "압박"을 적용하는 혜택을 제공

각 파일에 변환.

결과 출력에서 ​​여전히 uglifyjs을 실행하려고합니다.

+0

틀림없이 정확합니다! 그것은 내가 원래 원했던 것과 정확히 동일합니다. 나는 더 작은 묶음을 결과로 지금 가지고있는 해결책을 고수 할 것이다. 그러나 uglify는 덜 해킹 된 버전입니다. – Prinzhorn

+0

이렇게하면 사용자 정의 변환 단계와 크기가 동일한 번들이 만들어지고 프로젝트 변경 사항이 자동으로 적용됩니다. 이보다 더 작은 묶음을 얻는다면 묶음에 실제로 의존하는 코드가 제거되었을 가능성이 있습니다 – casr

0

나는 충분히 잘 작동하는 해결책을 찾았다 고 생각합니다. 보너스로 기존 코드를 터치 할 필요가 없습니다 (예 : process.env. 수표 추가). 나는 모듈/파일의 목록이 주어지면 require 콜을 {}으로 바꾼 브라우저 화 변환을 작성했다. 이렇게하면 결과 묶음에서 완전히 제거됩니다. 어쨌든 그냥 해킹 일뿐입니다. 알아.

전 :

var thing = require('./thing.js'); 
var pica = require('pica'); 

후 : 그것은 이미 makeRequireTransform 도우미를 제공하기 때문에 이것은 단지 몇 줄의 코드이었다 https://www.npmjs.com/package/browserify-transform-tools를 사용

var thing = {}; 
var pica = {}; 

. 코드를 여기에 버리고 당신이하는 일을 정확히 알지 않으면 아무도 사용하지 말 것을 권합니다.

derequire.js

var path = require('path'); 
var resolve = require('resolve'); 
var transformTools = require('browserify-transform-tools'); 

var options = { 
    evaluateArguments: true, 
    jsFilesOnly: true 
}; 

var cache = {}; 
var resolveDerequire = function(moduleName) { 
    var fromCache = cache[moduleName]; 

    if(fromCache) { 
     return fromCache; 
    } 

    return require.resolve(moduleName); 
}; 

var transform = transformTools.makeRequireTransform('derequire', options, function(args, transformOptions, done) { 
    var requiredModule = args[0]; 
    var basedir = path.dirname(transformOptions.file); 

    var shouldDerequire = transformOptions.config.modules.some(function(moduleToRequire) { 
     try { 
      //The normal require which respects NODE_PATH. 
      return require.resolve(requiredModule) === resolveDerequire(moduleToRequire); 
     } catch(ex1) { 
      try { 
       //A local require relative to the current file. 
       return resolve.sync(requiredModule, {basedir: basedir}) === resolveDerequire(moduleToRequire); 
      } catch(ex2) { 
       console.error(ex1, ex2); 
       return false; 
      } 
     } 
    }); 

    if(shouldDerequire) { 
     done(null, '{}'); 
    } else { 
     done(); 
    } 
}); 


module.exports = transform; 

패키지

.json으로 설정

"browserify": { 
    "transform": [ 
     "babelify", 
     [ 
      "./derequire.js", 
      { 
       "modules": [ 
        "pica", 
        "exif-js", 
        "./src/thing.js", 
        "components/TextEditor.jsx", 
        "lib/FileUploader.js" 
       ] 
      } 
     ], 
     "browserify-css", 
     "imgurify", 
     "glslify" 
    ] 
},