>웹 프론트엔드 >JS 튜토리얼 >Webpack 모듈을 사용하여 Library를 패키징하는 원리 및 구현

Webpack 모듈을 사용하여 Library를 패키징하는 원리 및 구현

亚连
亚连원래의
2018-05-31 13:53:281918검색

이 글은 주로 webpack 구성 모듈 패키징 라이브러리의 원리와 구현을 소개하고 있습니다.

이전 기사에서는 Webpack 패키징 JS 모듈의 기본 원리를 분석했습니다. 소개된 사례는 가장 일반적인 상황입니다. 즉, 여러 개의 JS 모듈과 하나의 입력 모듈이 하나의 번들 파일로 패키징되어 브라우저에서 직접 사용할 수 있거나 다른 JavaScript 엔진에 의한 실행은 완전한 실행 파일을 생성하기 위한 직접 컴파일과 동일합니다. 그러나 또 다른 매우 일반적인 상황이 있습니다. 즉, JavaScript 라이브러리를 구축하고 게시하려는 경우입니다. 예를 들어 npm 커뮤니티에 자신의 라이브러리를 게시하는 경우 Webpack에는 해당 구성이 필요하며 컴파일된 코드는 약간 다릅니다. .

이전 글과 마찬가지로 이번 글에서는 주로 Webpack에서 생성된 코드를 분석하고, 이를 결합하여 라이브러리 컴파일 시 Webpack의 라이브러리 구성 옵션의 구체적인 역할을 설명합니다. 해당 공식 문서는 여기에 있습니다.

JS 작성을 위한 라이브러리

간단한 라이브러리를 작성해 보겠습니다. util.js:

import $ from 'jquery'

function sayHello() {
 console.log("Hello");
}

function hideImages() {
 $('img').hide();
}

export default {
 sayHello: sayHello,
 hideImages: hideImages
}

두 가지 기능을 제공합니다. 물론 서로 관련이 없습니다. 실제로는 아무 쓸모가 없으며 순전히 교육 참고용으로만 사용됩니다. . .

다음으로 Webpack 구성을 작성합니다.

// 入口文件
entry: {
 util: './util.js',
}

// 输出文件
output: {
 path: './dist',
 filename: '[name].dist.js'
}

하지만 이것만으로는 부족하고, 출력 파일은 즉시 실행되는 함수이고, 최종적으로 util.js의 내보내기가 반환됩니다. 이전 기사에서 분석한 바에 따르면 최종 생성된 번들 코드 구조는 대략 다음과 같습니다.

(function(modules) {
 var installedModules = {};
 
 function webpack_require(moduleId) {
   // ...
 }

 return webpack_require('./util.js');
}) ({
 './util.js': generated_util,
 '/path/to/jquery.js': generated_jquery
});

실행하면 util.js의 내보내기 부분만 반환되며 필요한 것은 다음과 같습니다. 이 반환 값을 컴파일된 파일의 module.export에 제공하여 컴파일된 파일이 다른 사람이 가져올 수 있는 라이브러리가 되도록 합니다. 따라서 우리가 얻고자 하는 컴파일된 파일은 다음과 같아야 합니다.

module.exports = (function(modules) {
 var installedModules = {};
 function webpack_require(moduleId) {
   // ...
 }
 return webpack_require('./util.js');
}) ({
 './util.js': generated_util,
 '/path/to/jquery.js': generated_jquery
});

이러한 결과를 얻으려면 Webpack 구성의 출력 부분에 라이브러리 정보를 추가해야 합니다.

// 入口文件
output: {
 path: './dist',
 filename: '[name].dist.js',

 library: 'util',
 libraryTarget: commonjs2
}

The 여기서 가장 중요한 것은 libraryTarget입니다. 이제 commonjs2 형식을 사용하면 위의 컴파일 결과를 얻을 수 있습니다. 이는 Webpack 라이브러리가 최종 출력을 CommonJS 형식으로 내보내어 라이브러리 출시를 실현한다는 것을 의미합니다.

다른 게시 형식

libraryTarget에는 commonjs2 외에도 다른 옵션이 있습니다.

var (默认值,发布为全局变量)
commonjs
commonjs2
amd
umd

다른 옵션을 사용하면 컴파일된 파일을 다른 JavaScript 실행 환경에서 사용할 수 있습니다. 여기에서 Tiger Balm umd 형식의 출력이 어떻게 보이는지 직접 볼 수 있습니다.

(function webpackUniversalModuleDefinition(root, factory) {
 if(typeof exports === 'object' && typeof module === 'object') // commonjs2
  module.exports = factory();
 else if(typeof define === 'function' && define.amd)
  define("util", [], factory); // amd
 else if(typeof exports === 'object')
  exports["util"] = factory(); // commonjs
 else
  root["util"] = factory(); // var
}) (window, function() {
 return (function(modules) {
  var installedModules = {};
  function webpack_require(moduleId) {
    // ...
  }
  return webpack_require('./util.js');
 }) ({
  './util.js': generated_util,
  '/path/to/jquery.js': generated_jquery
 });
}

는 다양한 경우를 처리해야 하기 때문에 이전 commonjs2 상황보다 훨씬 더 복잡하지만 실제로 다음 부분은 유사합니다. 가장 중요한 것은 umd 모듈을 작성하는 표준 방법인 처음 몇 줄입니다. 실제로 모듈을 로드하는 함수인 전달된 팩토리 함수를 실행한 다음, 다양한 운영 환경에 따라 반환된 결과를 해당 개체에 전달합니다. 예를 들어, var는 결과를 브라우저에서 3f1c4e4b6b16bbbd69b2ee476dc4f83a 태그를 통해 직접 가져오는 데 사용되는 전역 변수로 설정합니다. AMD 환경이므로 표준 AMD 쓰기도 사용됩니다. 이러한 방식으로 게시된 JS 라이브러리는 어떤 환경에서든 다른 사람이 사용할 수 있습니다.

targetExport는 출력 내용을 제어합니다

패키징에 umd 형식을 사용하는 경우 예제 util과 같이 ES6 형식 내보내기 기본값을 사용하여 라이브러리의 소스 코드가 출력되는 경우 주의해야 할 함정이 있을 수 있습니다. 위의 .js를 사용하는 경우 컴파일된 JS 라이브러리 파일을 브라우저에 직접 넣어 사용할 수 있습니다. 이는 <script> 또는 RequireJS일 수 있으며 원하는 결과를 얻지 못할 수도 있습니다. 이는 JS 파일이 다음과 같은 객체를 반환하기 때문입니다. 예상한 객체 대신 </script>

{
 &#39;default&#39;: {
  sayHello: sayHello,
  hideImages: hideImages
 }
}

{
 sayHello: sayHello,
 hideImages: hideImages
}

브라우저뿐만 아니라 ES6을 지원하지 않는 모듈 시스템에서도 이 문제 기본값을 모르기 때문에 발생합니다. 따라서 컴파일된 JS 파일은 실제로 Webpack 구성에서 targetExport로 제어해야 하는 기본값만 출력해야 합니다.

library: 'util',
libraryTarget: umd,
targetExport: 'default'

모듈 로딩 기능 공장에서는 반환 값 뒤에 ['default']를 추가하므로 내보내기의 기본 부분만 반환됩니다.

이 함정은 실제로 umd 형식에서 밟기 매우 쉽습니다. 예를 들어 Vue 구성 요소를 게시하는 경우 .vue 파일의 JavaScript 부분은 일반적으로 다음과 같이 구성 요소 개체를 내보내기 기본 형식으로 내보냅니다.

export default {
 name: &#39;xxx&#39;,
 data: {
  return // ...
 },
 props: {
  // ...
 }
 methods: {
  // ...
 }
}

컴파일된 JS 파일을 브라우저에서 직접 실행하고 CDN을 사용하여 3f1c4e4b6b16bbbd69b2ee476dc4f83a를 통해 Vue를 로드하면 가져오는 개체가 너무 많아서 Vue가 이 구성 요소를 인식할 수 없다는 것을 알게 됩니다. 불필요한 기본 레이어 추가됩니다.

출력 내용을 기본값으로 변경하면 ES6 환경에서 이 모듈을 사용하는 데 영향을 미치나요? 일반적으로 말하면 아니오. 이전 기사에서 언급했듯이 Webpack의 생성된 코드는 모듈을 도입할 때 __esModule이라는 값을 통해 ES6 형식으로 내보내기인지 여부를 설정하고 결정합니다. 이제 기본 부분만 내보내면 이 개체는 비-형식으로 간주됩니다. ES6에는 __esModule이 포함되어 있지 않기 때문입니다. 이런 식으로 다른 모듈이 가져오기를 통해 이 모듈을 도입하면 전체 개체를 가져오게 되는데, 이는 실제로 위장한 원래 모듈의 내보내기 기본 부분만 가져오는 것과 같습니다.

물론, 위 논의의 전제는 내보내는 데 필요한 모든 콘텐츠가 내보내기 기본값이라는 것입니다. 기본 내보내기와 일반 내보내기가 모두 있는 경우 컴파일된 파일에서 기본 부분만 내보내는 것은 분명히 불가능합니다.

위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.

관련 기사:

200줄의 블록체인 구현 코드 블록체인 예제에 대한 자세한 설명

vue 페이스북 트위터를 사용하여 예제 공유

react는 create-react-app을 기반으로 프로젝트를 생성합니다

위 내용은 Webpack 모듈을 사용하여 Library를 패키징하는 원리 및 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.