IT story

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

hot-time 2020. 5. 29. 23:42
반응형

공급 업체 스크립트를 개별적으로 번들로 묶고 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 검색 변경


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

공급 업체 번들.

You should use CommonsChunkPlugin for that. in the configuration you specify the name of the chunk (e.g. vendor), and file name that will be generated (vendor.js).

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

Now important part, you have to now specify what does it mean vendor library and you do that in an entry section. One one more item to entry list with the same name as the name of the newly declared chunk (i.e. 'vendor' in this case). The value of that entry should be the list of all the modules that you want to move to vendor bundle. in your case it should look something like:

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

JQuery as global

Had the same problem and solved it with ProvidePlugin. here you are not defining global object but kind of shurtcuts to modules. i.e. you can configure it like that:

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

And now you can just use $ anywhere in your code - webpack will automatically convert that to

require('jquery')

I hope it helped. you can also look at my webpack configuration file that is here

I love webpack, but I agree that the documentation is not the nicest one in the world... but hey.. people were saying same thing about Angular documentation in the begining :)


Edit:

To have entrypoint-specific vendor chunks just use CommonsChunkPlugins multiple times:

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

and then declare different extenral libraries for different files:

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

If some libraries are overlapping (and for most of them) between entry points then you can extract them to common file using same plugin just with different configuration. See this example.


In case you're interested in bundling automatically your scripts separately from vendors ones:

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'})
  ]
};

You can read more about this feature in official documentation.


Also not sure if I fully understand your case, but here is config snippet to create separate vendor chunks for each of your bundles:

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
  }),
]

And link to CommonsChunkPlugin docs: http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin

참고URL : https://stackoverflow.com/questions/30329337/how-to-bundle-vendor-scripts-separately-and-require-them-as-needed-with-webpack

반응형