Webpack ProvidePlugin 대 외부?


84

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

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

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

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

감사

답변:


153

두 가지 모두 가능합니다. 라이브러리를 포함 <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: 모듈 내에서 자유 변수로 사용할 수있는 모듈 만들기

추가해야 new하기 전에 webpack.ProvidePlugin webpack.github.io/docs/list-of-plugins.html
MK 영에게

스크립트 로더를 사용하지 않는 이유는 무엇입니까? @dtothefp 설명처럼이 훨씬 쉽습니다
timaschew

내 webpack.config 파일이 javascript라는 폴더에 있고 그 안에 jquery 파일과 함께 vendor라는 폴더가 있습니다. 경로가 아니어야합니다. 해결 : {별칭 : {jquery : "vendor / jquery-1.10.2.js"}}. 여전히 별칭을 사용하는 나를 위해 작동하지 않습니다
me-me

3
alias 옵션에 절대 경로를 전달하십시오. 상대 경로를 전달하면 webpack 1의 require / import 위치에 상대적입니다. webpack 2에서는 webpack.config.js 파일 resp에 상대적입니다. 컨텍스트 옵션.
Tobias K.

@TobiasK. 절대 경로는 기본 내보내기와 협력하지 않습니다. 파일 {__esModule: true, default: MY_DEFAULT_EXPORT}대신 개체 를 얻고 MY_DEFAULT_EXPORT있습니다.
mgol

25

주목할만한 점은 속성 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을 참조 하지만 클로저로 전달되고 있음을 알 수 있습니다. 이것이 의도 된 기능인지 행운의 해킹인지는 확실하지 않지만 내 사용 사례에 잘 작동하는 것 같습니다.


당신이 require/import그것에 가지 않으면 플러그인이 필요하지 않았습니다 . $그것이 무엇이든 상관없이 글로벌 범위에 도달하기 때문에 작동합니다. 는 ProviderPlugin이 비싼 플러그인의 눈에 띄게 빌드 시간을 추가 할 수 있도록 AST 구문 분석이 필요합니다. 그래서 그것은 기본적으로 낭비입니다.
faceyspacey.com

@dtohefp이 대답은 신의 선물입니다. 모듈을 외부에 추가하지 않는 한 왜 ProvidePlugin객체를 반환 했는지 설명 할 수 있습니까 myModule.default? 직접적인 관계가있을 줄은 몰랐습니다.
Slbox

11

나는 이것이 오래된 포스트라는 것을 알고 있지만,이 경우에도 웹팩 스크립트 로더가 유용 할 수 있다는 것을 언급하는 것이 유용 할 것이라고 생각했습니다. 웹팩 문서에서 :

"스크립트 : 스크립트 태그와 같이 전역 컨텍스트에서 JavaScript 파일을 한 번 실행합니다. require는 구문 분석되지 않습니다."

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

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

JS 공급 업체 파일과 앱 파일을 함께 연결하는 이전 빌드 프로세스를 마이그레이션 할 때 특히 유용합니다. 경고의 한마디는 스크립트 로더 require()가 오버로딩을 통해서만 작동하는 것처럼 보이며 webpack.config 파일 내에서 지정하여 알 수있는 한 작동하지 않는다는 것입니다. 많은 사람들이 오버로딩 require이 나쁜 관행 이라고 주장하지만, 하나의 번들에서 공급 업체와 앱 스크립트를 연결하는 동시에 추가 웹팩 번들로 shimm 할 필요가없는 JS Globals를 노출하는 데 매우 유용 할 수 있습니다. 예를 들면 :

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

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

이렇게하면 $ .cookie, History 및 moment를이 번들 내부와 외부에서 전역 적으로 사용할 수 있으며 이러한 공급 업체 라이브러리를 main.js 스크립트 및 모든 required 파일 과 함께 번들로 제공 합니다.

또한이 기술에 유용한 것은 다음과 같습니다.

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

Bower를 사용하는 mainrequired 라이브러리 package.json 의 파일을 살펴 봅니다 . 위의 예에서 History.js에는 main지정된 파일 이 없으므로 파일 경로가 필요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.