developer tip

Webpack ProvidePlugin 대 외부?

optionbox 2020. 10. 7. 07:33
반응형

Webpack ProvidePlugin 대 외부?


Backbone.js 와 함께 Webpack 을 사용하는 아이디어를 탐색 중 입니다.

빠른 시작 가이드를 따랐고 Webpack이 어떻게 작동하는지에 대한 일반적인 아이디어가 있지만 jquery / backbone / underscore와 같은 종속성 라이브러리를로드하는 방법에 대해서는 명확하지 않습니다.

외부에서로드해야합니까 <script>아니면 Webpack이 RequireJS의 shim처럼 처리 할 수 ​​있습니까?

에 따르면 웹팩 문서 : 모듈을 shimming , ProvidePlugin그리고 externals이 관련이있을 것 같다 (그렇다 bundle!로더 곳)하지만 난 어떤 사용하면 알아낼 수 없습니다.

감사


두 가지 모두 가능합니다. 라이브러리를 포함 <script>(즉, CDN의 라이브러리 사용)하거나 생성 된 번들에 포함 할 수 있습니다.

<script>태그 를 통해로드하는 경우 모듈 externals에 쓰기를 허용 하는 옵션을 사용할 수 있습니다 require(...).

CDN의 라이브러리를 사용한 예 :

<script src="https://code.jquery.com/jquery-git2.min.js"></script>

// the artifial module "jquery" exports the global var "jQuery"
externals: { jquery: "jQuery" }

// inside any module
var $ = require("jquery");

번들에 포함 된 라이브러리의 예 :

copy `jquery-git2.min.js` to your local filesystem

// make "jquery" resolve to your local copy of the library
// i. e. through the resolve.alias option
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } }

// inside any module
var $ = require("jquery");

ProvidePlugin모듈을 (무료) 변수에 매핑 할 수 있습니다. 따라서 다음과 같이 정의 할 수 있습니다. " xyz모듈 내 에서 (무료) 변수를 사용할 때마다 (웹팩)은로 설정해야 xyz합니다 require("abc")."

없는 예 ProvidePlugin:

// You need to require underscore before you can use it
var _ = require("underscore");
_.size(...);

ProvidePlugin:

plugins: [
  new webpack.ProvidePlugin({
    "_": "underscore"
  }) 
]

// If you use "_", underscore is automatically required
_.size(...)

요약:

  • CDN의 라이브러리 : <script>태그 및 externals옵션 사용
  • 파일 시스템의 라이브러리 : 번들에 라이브러리를 포함합니다. ( resolve라이브러리를 찾기 위해 옵션을 수정할 수 있음)
  • externals: 전역 변수를 모듈로 사용할 수 있도록합니다.
  • ProvidePlugin: 모듈 내에서 자유 변수로 모듈을 사용할 수 있도록합니다.

주목할만한 점은 속성 ProvidePlugin과 함께 를 사용하면 명시 적으로 지정할 필요없이 웹팩 모듈 클로저에 전달할 수 있다는 것입니다. 이는 .NET을 참조하는 많은 다른 파일로 레거시 코드를 리팩토링하는 데 유용 할 수 있습니다 .externalsjQueryrequire$

//webpack.config.js
module.exports = {
  entry: './index.js',
  output: { 
    filename: '[name].js' 
  },
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
    })
  ]
};

이제 index.js에서

console.log(typeof $ === 'function');

다음과 같은 컴파일 된 출력이 webpackBootstrap클로저에 전달됩니다 .

/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

    /* WEBPACK VAR INJECTION */(function($) {
        console.log(typeof $ === 'function');

    /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

    module.exports = jQuery;

/***/ }
/******/ ])

따라서 CDN에서 $전역 / 창 jQuery참조 하지만 클로저로 전달되는 것을 볼 수 있습니다. 이것이 의도 된 기능인지 행운의 해킹인지는 확실하지 않지만 내 사용 사례에 잘 작동하는 것 같습니다.


I know this is an old post but thought it would be useful to mention that the webpack script loader may be useful in this case as well. From the webpack docs:

"script: Executes a JavaScript file once in global context (like in script tag), requires are not parsed."

http://webpack.github.io/docs/list-of-loaders.html

https://github.com/webpack/script-loader

I have found this particularly useful when migrating older build processes that concat JS vendor files and app files together. A word of warning is that the script loader seems only to work through overloading require() and doesn't work as far as I can tell by being specified within a webpack.config file. Although, many argue that overloading require is bad practice, it can be quite useful for concating vendor and app script in one bundle, and at the same time exposing JS Globals that don't have to be shimmed into addition webpack bundles. For example:

require('script!jquery-cookie/jquery.cookie');
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history');
require('script!momentjs');

require('./scripts/main.js');

This would make $.cookie, History, and moment globally available inside and outside of this bundle, and bundle these vendor libs with the main.js script and all it's required files.

Also, useful with this technique is:

resolve: {
  extensions: ["", ".js"],
  modulesDirectories: ['node_modules', 'bower_components']
},
plugins: [
  new webpack.ResolverPlugin(
    new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
   )
]

which is using Bower, will look at the main file in each required libraries package.json. In the above example, History.js doesn't have a main file specified, so the path to the file is necessary.

참고URL : https://stackoverflow.com/questions/23305599/webpack-provideplugin-vs-externals

반응형