当前位置: 首页 > 科技观察

如何使用Webpack实现模块化打包?

时间:2023-03-17 13:05:58 科技观察

本文转载自微信公众号《前端引力》,作者一川。转载本文请联系前端Gravity公众号。前面写过,我们知道目前生产中主流的模块化打包工具有Webpack、Parcel和Rollup。作为模块化打包工具,它们的基本特点是:可以将分散的模块打包在一起可以编译改造代码中的新特性,使其兼容各种生产环境对于主流的webpack来说,webpack是一个模块打包工具,模块化代码打包的问题可以解决自己实现,可以通过webpack将零散的JS代码打包成一个JS文件。对于存在环境兼容问题的代码,webpack可以在代码打包过程中通过loader机制对其进行编译转换,然后进行打包。针对不同类型的前端模块,webpack支持模块化加载js中任意类型的资源文件,例如:CSS文件可以通过webpack加载到JS中,加载后的CSS文件会被工具化为style标签。webpack还有代码拆分的能力,可以根据需要将应用中的所有模块打包成块,不用担心将所有代码打包在一起,导致单个文件过大,导致加载缓慢。这种按需分块打包的模块非常适合大型web项目。Webpack在路上Webpack作为主流的前端模块打包器,提供了一套完整的前端项目模块化解决方案,不局限于JS模块化,可以实现前端项目开发过程中涉及的资源模块化.我们知道ESModules中指定的html使用script导入js模块,需要设置type="module"来区分是普通的JS脚本还是加载的模块。支持ESModules的浏览器可以直接使用,不支持的浏览器会报错,所以需要使用webpack模块打包工具来避免报错。//heading.jsexportdefaultfunction(){constelement=document.createElement("div");element.textContent="helloyichuan";element.addEventListener("click",()=>{console.log("helloonechuan");returnelement})}//index.jsimportcreateHeaderfrom"./heading.js";document.body.append(createHeader())为,我们需要首先安装webpack的核心模块和cli程序,用于命令行调用webpack。npx是npm5.2之后新增的命令,可以更方便的执行项目node_modules中的远程模块或者cli程序。$npminit--yes$npmiwebpackwebpack-cli-D$npxwebpack--version$npxwebpack通过执行npxwebpack实现自动打包,webpack默认会从src/index.js文件开始打包,会在根目录下产生一个dist目录打包后的目录,所有打包后的文件都会在dist目录下。|--dist|--main.js(()=>{"usestrict";document.body.append(function(){conste=document.createElement("div");e.textContent="helloyichuan",e.addEventListener("点击",(()=>(console.log("helloonechuan"),e)))}())})();webpack4.0及以后版本支持零配置直接开始打包,整个过程会按照约定使用src/index.js文件作为打包入口,最终打包结果存放在dis/main.js中.但是很多时候webpack默认的规则并不能满足我们的实际需求,所以我们需要自定义webpack的配置。webpack支持在项目中创建webpack.config.js文件进行自定义打包配置。由于webpack运行在node.js环境中,因此它应该遵循CommonJS规则进行导入和导出。|--backpack|--src|--heading.js|--main.js|--index.html|--package.json|--webpack.config.js------webpack配置文件webpack自定义配置文件://webpack.config.jsconstpath=require("path");module.exports={entry:"./src/index.js",//packageentryoutput:{//packageexportfilename:"bundle.js",//命名打包文件path:path.join(__dirname,"output")},//打包模式mode:"none"}执行打包命令后,会自动显示在根目录directoryoftheproject生成打包的文件目录,我们看到下面是执行打包命令后生成的文件,生成的函数是立即执行的函数。/******/(function(modules){//webpackBootstrapfunction/******///模块缓存/******/variinstalledModules={};/******//******///Therequirefunction/******/function__webpack_require__(moduleId){/******//******///Checkifmoduleisincache/******/if(installedModules[moduleId]){/******/returninstalledModules[moduleId].exports;/******/}/******///Createanewmodule(andputitintothecache)/******/varmodule=installedModules[moduleId]={/******/i:moduleId,/******/l:false,/******/exports:{}/******/};/******//******///执行模块函数/******/modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);/******//******///Flagthemoduleasloaded/******/module.l=true;/******//******///Returntheexportsofthemodule/******/returnmodule.exports;/******/}/******//******//******///exposethemodulesobject(__webpack_modules__)/******/__webpack_require__.m=modules;/******//******///exposethemodulescache/******/__webpack_require__.c=installedModules;/******//******///definegetterfunctionforharmonyexports/******/__webpack_require__.d=function(exports,name,getter){/******/if(!__webpack_require__.o(exports,name)){/******/Object.defineProperty(exports,name,{enumerable:true,get:getter});/******/}/******/};/******//******///define__esModuleoneexports/******/__webpack_require__.r=function(exports){/******/if(typeofSymbol!=='undefined'&&Symbol.toStringTag){/******/Object.defineProperty(exports,Symbol.toStringTag,{value:'Module'});/******/}/******/Object.defineProperty(exports,'__esModule',{value:true});/******/};/******//******///createafakenamespaceobject/******///mode&1:valueisamoduleid,requireit/******///mode&2:mergeallpropertiesofvalueintothens/******///mode&4:returnvaluewhenalreadynsobject/******///mode&8|1:behavelikerequire/******/__webpack_require__.t=function(value,mode){/******/if(mode&1)value=__webpack_require__(value);/******/if(mode&8)returnvalue;/******/if((模式&4)&&typeofvalue==='object'&&value&&value.__esModule)returnvalue;/******/varns=Object.create(null);/******/__webpack_require__.r(ns);/******/Object.defineProperty(ns,'default',{enumerable:true,value:value});/******/if(mode&2&&typeofvalue!='string')for(varkeyinvalue)__webpack_require__.d(ns,key,function(key){returnvalue[key];}.bind(null,key));/******/returnns;/******/};/******//******///getDefaultExportfunctionforcompatibilitywithnon-harmonymodules/******/__webpack_require__.n=function(module){/******/vargetter=module&&module.__esModule?/******/functiongetDefault(){returnmodule['default'];}:/******/functiongetModuleExports(){returnmodule;};/******/__webpack_require__.d(getter,'a',getter);/******/returngetter;/******/};/******//******///Object.prototype.hasOwnProperty.call/******/__webpack_require__.o=function(object,property){returnObject.prototype.hasOwnProperty.call(object,property);};/******//******///__我们bpack_public_path__/******/__webpack_require__.p="";/******//******//******///Loadentrymoduleandreturnexports/******/return__webpack_require__(__webpack_require__.s="./src/index.js");/******/})/****************************************************************************//******/({/***/"./src/heading.js":/*!*************************!*\!***./src/heading.js***!\************************//*!exportsprovided:default*//***/(function(module,__webpack_exports__,__webpack_require__){"usestrict";eval("__webpack_require__.r(__webpack_exports__);\n//heading.js\n/*harmonydefaultexport*/__webpack_exports__[\"default\"]=(function(){\nconstelement=document.createElement(\"div\");\nelement.textContent=\"helloyichuan\";\nelement.addEventListener(\"click\",()=>{\nconsole.log(\"helloonechuan\");\nreturnelement\n})\n});\n\n//#sourceURL=webpack:///./src/heading.js?");/***/}),/***/"./src/index.js":/*!************************!*\!***。/src/index.js***!\*************************//*!noexportsprovided*//***/(函数(模块,__webpack_exports__,__webpack_require__){"usestrict";eval("__webpack_require__.r(__webpack_exports__);\n/*harmonyimport*/var_heading_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(/*!./heading.js*/\"./src/heading.js\");\n//index.js\n\ndocument.body.append(Object(_heading_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"])())\n\n//#sourceURL=webpack:///./src/index.js?");/***/})/******/});在上面的打包文件中,src目录下的每个模块都对应着打包文件中的一个函数,为了实现模块的私有作用域,在这个文件中还挂载了一些其他的数据和工具函数。这篇文章主要写的是webpack在路上的使用。webpack的基本使用并不是很复杂,尤其是在webpack4.0之后,简化了很多配置。在这个配置不复杂的前提下,开发者对它的掌握程度主要体现在能否理解它的工作机制和原理。