[javascript] 공급 업체 스크립트를 개별적으로 번들로 묶고 Webpack과 함께 필요에 따라 필요한 방법은 무엇입니까?

나는 가능하다고 생각되는 것을하려고 노력하고 있지만 실제로는 웹 팩 문서에서 어떻게 해야하는지 이해할 수 없습니다.

서로 의존 할 수도 있고 그렇지 않을 수도있는 여러 모듈로 JavaScript 라이브러리를 작성 중입니다. 또한 jQuery는 모든 모듈에서 사용되며 일부 모듈에는 jQuery 플러그인이 필요할 수 있습니다. 이 라이브러리는 여러 다른 웹 사이트에서 사용되며 일부 또는 모든 모듈이 필요할 수 있습니다.

내 모듈 간의 종속성을 정의하는 것은 매우 쉽지만 타사 종속성을 정의하는 것이 예상보다 어렵습니다.

내가 달성하고자하는 것 : 각 응용 프로그램마다 필요한 타사 종속성이있는 번들 파일과 라이브러리의 필요한 모듈이있는 두 개의 번들 파일을 원합니다.

: 내 라이브러리에 다음 모듈이 있다고 상상해 봅시다.

  • a (필수 : jquery, jquery.plugin1)
  • b (필수 : jquery, a)
  • c (필수 : jquery, jquery.ui, a, b)
  • d (필수 : jquery, jquery.plugin2, a)

그리고 모듈 a, b 및 c가 필요한 앱이 있습니다 (고유 항목 파일로 참조하십시오). 이 경우 웹팩은 다음 파일을 생성해야합니다.

  • 공급 업체 번들 : jquery, jquery.plugin1 및 jquery.ui 사용;
  • 웹 사이트 번들 : 모듈 a, b 및 c;

결국 jQuery를 전역으로 사용하기를 원하므로 모든 단일 파일에서 필요하지 않습니다 (예 : 기본 파일에서만 필요). 그리고 jQuery 플러그인은 필요한 경우 $ 전역을 확장합니다 (필요하지 않은 다른 모듈에서 사용할 수 있다면 문제가되지 않습니다).

이것이 가능하다고 가정하면이 경우 웹팩 구성 파일의 예는 무엇입니까? 구성 파일에서 로더, 외부 장치 및 플러그인의 여러 조합을 시도했지만 실제로 수행중인 작업과 사용해야하는 것을 얻지 못했습니다. 감사합니다!



답변

내 webpack.config.js (버전 1,2,3) 파일에서

function isExternal(module) {
  var context = module.context;

  if (typeof context !== 'string') {
    return false;
  }

  return context.indexOf('node_modules') !== -1;
}

내 플러그인 배열에서

plugins: [
  new CommonsChunkPlugin({
    name: 'vendors',
    minChunks: function(module) {
      return isExternal(module);
    }
  }),
  // Other plugins
]

이제 필요에 따라 타사 라이브러리를 하나의 파일에만 추가하는 파일이 있습니다.

공급 업체와 진입 점 파일을 분리하는 위치를 더 세분화하려면 다음을 수행하십시오.

plugins: [
  new CommonsChunkPlugin({
    name: 'common',
    minChunks: function(module, count) {
      return !isExternal(module) && count >= 2; // adjustable
    }
  }),
  new CommonsChunkPlugin({
    name: 'vendors',
    chunks: ['common'],
    // or if you have an key value object for your entries
    // chunks: Object.keys(entry).concat('common')
    minChunks: function(module) {
      return isExternal(module);
    }
  })
]

플러그인 순서는 매우 중요합니다.

또한 이것은 버전 4에서 변경 될 예정입니다. 공식적인 경우이 답변을 업데이트합니다.

업데이트 : Windows 사용자를위한 indexOf 검색 변경


답변

문제를 완전히 이해했는지 잘 모르겠지만 최근에 비슷한 문제가 발생했기 때문에 도와 드리겠습니다.

공급 업체 번들.

이를 위해 CommonsChunkPlugin 을 사용해야 합니다. 구성에서 청크 이름 (예 🙂 vendor과 생성 될 파일 이름 ( vendor.js)을 지정합니다.

new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),

이제 중요한 부분은 vendor라이브러리의 의미를 지정해야 하며 항목 섹션에서이를 수행하는 것입니다. 새로 선언 된 청크의 이름과 같은 이름을 가진 항목 목록에 항목이 하나 더 있습니다 (이 경우 ‘공급 업체’). 해당 항목의 값은 vendor번들 로 이동하려는 모든 모듈의 목록이어야합니다 . 귀하의 경우 다음과 같이 보일 것입니다 :

entry: {
    app: 'entry.js',
    vendor: ['jquery', 'jquery.plugin1']
}

글로벌 JQuery

같은 문제가 있었고 ProvidePlugin으로 해결했습니다 . 여기서는 전역 객체를 정의하지 않고 모듈에 대한 일종의 셔트 컷을 정의합니다. 즉, 다음과 같이 구성 할 수 있습니다.

new webpack.ProvidePlugin({
    $: "jquery"
})

이제 $코드의 어느 곳에서나 사용할 수 있습니다. 웹팩은 자동으로

require('jquery')

도움이 되었기를 바랍니다. 여기에 있는 내 웹 팩 구성 파일을 볼 수도 있습니다

나는 webpack을 좋아하지만 문서가 세상에서 가장 좋은 것은 아니지만 동의합니다.하지만 사람들은 처음에 Angular 문서에 대해 같은 것을 말하고 있습니다 🙂


편집하다:

진입 점 특정 벤더 청크를 사용하려면 CommonsChunkPlugins를 여러 번 사용하십시오.

new webpack.optimize.CommonsChunkPlugin("vendor-page1", "vendor-page1.js", Infinity),
new webpack.optimize.CommonsChunkPlugin("vendor-page2", "vendor-page2.js", Infinity),

그런 다음 다른 파일에 대해 다른 외부 라이브러리를 선언하십시오.

entry: {
    page1: ['entry.js'],
    page2: ['entry2.js'],
    "vendor-page1": [
        'lodash'
    ],
    "vendor-page2": [
        'jquery'
    ]
},

일부 라이브러리가 진입 점간에 겹치고 (그리고 대부분의 경우) 다른 구성을 가진 동일한 플러그인을 사용하여 공통 파일로 추출 할 수 있습니다. 예를 참조하십시오 .


답변

스크립트를 공급 업체 스크립트와 별도로 자동 번들링하는 데 관심이있는 경우 :

var webpack = require('webpack'),
    pkg     = require('./package.json'),  //loads npm config file
    html    = require('html-webpack-plugin');

module.exports = {
  context : __dirname + '/app',
  entry   : {
    app     : __dirname + '/app/index.js',
    vendor  : Object.keys(pkg.dependencies) //get npm vendors deps from config
  },
  output  : {
    path      : __dirname + '/dist',
    filename  : 'app.min-[hash:6].js'
  },
  plugins: [
    //Finally add this line to bundle the vendor code separately
    new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.min-[hash:6].js'),
    new html({template : __dirname + '/app/index.html'})
  ]
};

이 기능에 대한 자세한 내용은 공식 문서를 참조하십시오 .


답변

또한 귀하의 사례를 완전히 이해했는지 확실하지 않지만 다음은 각 번들에 대해 별도의 공급 업체 청크를 생성하는 구성 스 니펫입니다.

entry: {
  bundle1: './build/bundles/bundle1.js',
  bundle2: './build/bundles/bundle2.js',
  'vendor-bundle1': [
    'react',
    'react-router'
  ],
  'vendor-bundle2': [
    'react',
    'react-router',
    'flummox',
    'immutable'
  ]
},

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor-bundle1',
    chunks: ['bundle1'],
    filename: 'vendor-bundle1.js',
    minChunks: Infinity
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor-bundle2',
    chunks: ['bundle2'],
    filename: 'vendor-bundle2-whatever.js',
    minChunks: Infinity
  }),
]

CommonsChunkPlugin문서에 연결 하십시오 : http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin


답변