资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,#,什么是,WebPack,,为什么要使用它?,WebPack,可以看做是,模块打包机,:它做的事情是,分析你的项目结构,找到,JavaScript,模块以及其它的一些浏览器不能直接运行的拓展语言(,Scss,,,TypeScript,等),并将其转换和打包为合适的格式供浏览器使用。,现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的,JavaScript,代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法,模块化,让我们可以把复杂的程序细化为小的文件,;,类似于,TypeScript,这种在,JavaScript,基础上拓展的开发语言:使我们能够实现目前版本的,JavaScript,不能直接使用的特性,并且之后还能转换为,JavaScript,文件使浏览器可以识别;,Scss,,,less,等,CSS,预处理器,这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为,WebPack,类的工具的出现提供了需求。,1,WebPack,和,Grunt,以及,Gulp,相比有什么特性,其实,Webpack,和另外两个并没有太多的可比性,,Gulp/Grunt,是一种能够优化前端的开发流程的工具,而,WebPack,是一种模块化的解决方案,,不过,Webpack,的优点使得,Webpack,在很多场景下可以替代,Gulp/Grunt,类的工具。,Grunt,和,Gulp,的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。,2,Webpack,的工作方式,Webpack,的工作方式是:,把你的项目当做一个整体,通过一个给定的主文件(如:,index.js,),,Webpack,将从这个文件开始找到你的项目的所有依赖文件,使用,loaders,处理它们,最后打包为一个(或多个)浏览器可识别的,JavaScript,文件。,3,开始使用,Webpack,安装(前提是,node.js,已安装),Webpack,可以使用,npm,安装,新建一个空的练习文件夹(此处命名为,webpack-demo,),在终端中转到该文件夹后执行下述指令就可以完成安装。,首先跳转到该文件夹下,cd webpack-demo,/,全局安装,npm install-g webpack,/,安装到你的项目目录,npm install-save-dev webpack,4,一,.,正式,使用,Webpack,/,创建文件,npm init,在上述练习文件夹中创建一个,package.json,文件,这是一个标准的,npm,说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。在终端中使用,npm init,命令可以自动创建这个,package.json,文件,输入这个命令后,终端会问你一系列诸如项目名称,项目描述,作者等信息,不过不用担心,如果你不准备在,npm,中发布你的模块,这些问题的答案都不重要,回车默认即可。,package.json,文件已经就绪,我们在本项目中安装,Webpack,作为依赖包,/,安装,Webpack,npm install-save-dev webpack,5,一,.,正式,使用,Webpack,回到之前的空文件夹,并在里面创建两个文件夹,app,文件夹和,public,文件夹,,app,文件夹用来存放原始数据和我们将写的,JavaScript,模块,,public,文件夹用来存放之后供浏览器读取的文件(包括使用,webpack,打包生成的,js,文件以及一个,index.html,文件)。接下来我们再创建三个文件,:,index.html-,放在,public,文件夹中,;,Greeter.js-,放在,app,文件夹中,;,main.js-,放在,app,文件夹中,;,此时项目结构如下图所示,6,一,.,正式,使用,Webpack,app,文件夹用来存放原始数据和我们将写的,JavaScript,模块。,public,文件夹用来存放之后供浏览器读取的文件(包括使用,webpack,打包生成的,js,文件以及一个,index.html,文件)。,7,一,.,正式,使用,Webpack,我们在,index.html,文件中写入最基础的,html,代码,它在这里目的在于引入打包后的,js,文件(这里我们先把之后打包后的,js,文件命名为,bundle.js,,之后我们还会详细讲述)。,webpack-demo,8,一,.,正式,使用,Webpack,我们在,Greeter.js,中定义一个返回包含问候信息的,html,元素的函数,并依据,CommonJS,规范导出这个函数为一个模块:,/Greeter.js,module.exports=function(),var greet=document.createElement(div);,greet.textContent=,Hi there and greetings!,;,return greet;,;,9,一,.,正式,使用,Webpack,main.js,文件中我们写入下述代码,用以把,Greeter,模块返回的节点插入页面。,/main.js,const greeter=require(,./Greeter.js,);,document.querySelector(#root).appendChild(greeter();,10,一,.,正式,使用,Webpack,webpack,在终端中使用,在基本的使用方法如下:,#extry file,出填写入口文件的路径,本文中就是上述,main.js,的路径,,#destination for bundled file,处填写打包文件的存放路径,#,填写路径的时候不用添加,webpack entry file-o destination for bundled file,(,全局安装的情况,),webpack app/main.js-o public/bundle.js,指定入口文件后,,webpack,将自动识别项目所依赖的其它文件,不过需要注意的是如果你的,webpack,不是全局安装的,那么当你在终端中使用此命令时,需要额外指定其在,node_modules,中的地址,继续上面的例子,在终端中输入如下命令,#webpack,非全局安装,的情况,node_modules/.bin/webpack app/main.js public/bundle.js,11,12,二,.,通过配置文件来使用,Webpack,通过配置文件来使用,Webpack,Webpack,拥有很多其它的比较高级的功能(比如说本文后面会介绍的,loaders,和,plugins,),这些功能其实都可以通过命令行模式实现,但是正如前面提到的,这样不太方便且容易出错的,更好的办法是定义一个配置文件,这个配置文件其实也是一个简单的,JavaScript,模块,我们可以把所有的与打包相关的信息放在里面。,13,二,.,通过配置文件来使用,Webpack,继续上面的例子来说明如何写这个配置文件,在当前练习,文件夹的根目录,下新建一个名为,webpack.config.js,的文件,我们在其中写入如下所示的简单配置代码,目前的配置主要涉及到的内容是入口文件路径和打包后文件的存放路径。,/webpack.config.js,module.exports=,entry:_dirname+/app/main.js,/,已多次提及的唯一入口文件,output:,path:_dirname+/public,/,打包后的文件存放的地方,filename:bundle.js/,打包后输出文件的文件名,注,:“,_dirname”,是,node.js,中的一个全局变量,它指向当前执行脚本所在的目录。,14,二,.,通过配置文件来使用,Webpack,有了这个配置之后,再打包文件,只需在终端里运行,webpack,(,非全局安装需使用,node_modules/.bin/webpack,),命令就可以了,这条命令会自动引用,webpack.config.js,文件中的配置选项,示例如下:,如果我们可以连,webpack(,非全局安装需使用,node_modules/.bin/webpack),这条命令都可以不用呢?,15,三,.,更快捷的执行打包任务,在命令行中输入命令需要代码类似于,node_modules/.bin/,webpack,这样的路径其实是比较烦人的,不过值得庆幸的是,npm,可以引导任务执行,对,npm,进行配置后可以在命令行中使用简单的,npm start,命令来替代上面略微繁琐的命令。在,package.json,中对,scripts,对象进行相关设置即可。,/,原有,package.json,内容,16,三,.,更快捷的执行打包任务,在,package.json,中对,scripts,对象进行相关设置即可。,name:webpack-demo,version:1.0.0,description:,scripts:,start:webpack/,修改的是这里,,JSON,文件不支持注释,引用时请清除,author:,license:ISC,devDependencies:,webpack:4.8.3,注:,package.json,中的,script,会按照一定顺序寻找命令对应位置,本地的,node_modules/.bin,路径就在这个寻找清单中,所以无论是全局还是局部安装的,Webpack,,你都不需要写前面那指明详细的路径了。,17,三,.,更快捷的执行打包任务,npm,的,start,命令是一个特殊的脚本名称,其特殊性表现在:,在命令行中使用,npm start,就可以执行其对于的命令,如果对应的此脚本名称不是,start,,想要在命令行中运行时,需要这样用,npm run script name,如,npm run build,,我们在命令行中输入,npm start,试试,输出结果如下:,npm start,18,四,.Webpack,的强大功能,生成,Source Maps,(使调试更容易),开发总是离不开调试,方便的调试能极大的提高开发效率,不过有时候通过打包后的文件,你是不容易找到出错了的地方,对应的你写的代码的位置的,,Source Maps,就是来帮我们解决这个问题的。,通过简单的配置,,webpack,就可以在打包时为我们生成的,source maps,,这为我们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。,19,四,.Webpack,的强大功能,在,webpack,的配置文件中配置,source maps,,需要配置,devtool,,它有以下四种不同的配置选项,各具优缺点,描述如下:,source-map,在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的,source map,,但是它会减慢打包速度;,cheap-module-source-map,在一个单独的文件中生成一个不带列映射的,map,,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便;,eval-source-map,使用,eval,打包源文件模块,在同一个文件中生成干净的完整的,source map,。这个选项可以在不影响构建速度的前提下生成完整的,sourcemap,,但是对打包后输出的,JS,文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项;,cheap-module-eval-source-map,这是在打包文件时最快的生成,source map,的方法,生成的,Source Map,会和打包后的,JavaScript,文件同行显示,没有列映射,和,eval-source-map,选项具有相似的缺点;,20,四,.Webpack,的强大功能,对小到中型的项目中,,eval-source-map,是一个很好的选项,再次强调你只应该开发阶段使用它,我们继续对上文新建的,webpack.config.js,,进行如下配置,:,module.exports=,devtool:,eval-source-map,entry:_dirname+,/app/main.js,output:,path:_dirname+,/public,filename:bundle.js,cheap-module-eval-source-map,方法构建速度更快,但是不利于调试,推荐在大型项目考虑时间成本时使用。,21,五,.,使用,webpack,构建本地服务器,让你的浏览器监听你的代码的修改,并自动刷新显示修改后的结果。,其实,Webpack,提供一个可选的本地开发服务器,这个本地服务器基于,node.js,构建,不过它是一个单独的组件,在,webpack,中进行配置之前需要,单独安装,它作为项目依赖。,/,本地开发服务器,npm install-save-dev webpack-dev-server,22,五,.,使用,webpack,构建本地服务器,把这些命令加到,webpack,的配置文件中,现在的配置文件,webpack.config.js,如下所示,/devserver,作为,webpack,配置选项中的一项,module.exports=,devtool:,eval-source-map,entry:_dirname+,/app/main.js,output:,path:_dirname+,/public,filename:,bundle.js,devServer:,contentBase:,./public,/,本地服务器所加载的页面所在的目录,historyApiFallback:true,/,不跳转,inline:true/,实时刷新,23,五,.,使用,webpack,构建本地服务器,在,package.json,中的,scripts,对象中添加如下命令,用以开启本地服务器:,scripts,:,test:,echo Error:no test specified&exit 1,start:,webpack,server:,webpack-dev-server-open,24,五,.,使用,webpack,构建本地服务器,在终端中输入,npm run server,即可在本地的,8080,端口查看结果,:,25,六,.webpack,插件,html-webpack-plugin,因为,index.html,文件太死了,连,js,文件都写死了,有时候引用的,js,文件是动态变化的呢?,打个比方,类似下面这种例子:,而且还不确定有多少个。,还有一种情况,有时候为了更好的,cache,处理,文件名还带着,hash,,例如下面这样:,main.9046fe2bf8166cbe16d7.js,这个,hash,是文件的,md5,值,随着文件的内容而变化,你总不能每变化一次,就改一下,index.html,文件吧?,效率太低!,26,2025/4/29 周二,安装,$,npm install html-webpack-plugin-save-dev,安装成功后,,package.json,这个文件会多出一行,html-webpack-plugin:2.30.1,,如下所示:,name:hello-wepback,a,version:1.0.0,description:,main:index.js,scripts:,dev:webpack-d-watch,prod:webpack-p,author:,license:ISC,devDependencies:,html-webpack-plugin:2.30.1,webpack:3.8.1,六,.webpack,插件,html-webpack-plugin,27,2025/4/29 周二,六,.webpack,插件,html-webpack-plugin,使用,现在我们把之前的,dist/index.html,先删除掉,我们要用,html-webpack-plugin,这个插件来自动生成它。,把,webpack.config.js,文件改一下,如下所示:,var HtmlWebpackPlugin=require(html-webpack-plugin);,module.exports=,entry:./app/main.js,output:,path:_dirname+/dist,filename:bundle.js,plugins:new HtmlWebpackPlugin(),;,最后,运行一下上文所说的,npm run dev,命令,你会发现在,dist,目录生成了,index.html,文件,打开来看下。,28,2025/4/29 周二,六,.webpack,插件,html-webpack-plugin,要改变,title,很简单,上文提到,HtmlWebpackPlugin,这个方法可以传入很多参数的,下面这样就可以解决这个问题。,var HtmlWebpackPlugin=require(html-webpack-plugin);,module.exports=,entry:./app/main.js,output:,path:_dirname+/dist,filename:bundle.js,plugins:new HtmlWebpackPlugin(,title:hello world,),;,29,2025/4/29 周二,六,.webpack,插件,html-webpack-plugin,要让,index.html,根据我们的意愿来生成。就是说它的内容是我们自己定的。,html-webpack-plugin,的,template,功能。,把,webpack.config.js,更改如下:,var HtmlWebpackPlugin=require(html-webpack-plugin);,module.exports=,entry:_dirname+/app/main.js,output:,path:_dirname+/public,filename:bundle.js,plugins:new HtmlWebpackPlugin(,template:./dist/index.html,),;,30,2025/4/29 周二,六,.webpack,插件,html-webpack-plugin,var HtmlWebpackPlugin=require(html-webpack-plugin);,module.exports=,entry:./app/main.js,output:,path:_dirname+/dist,filename:bundle.js,plugins:new HtmlWebpackPlugin(,template:./dist/index.html,filename:index.html,/,默认情况下生成的,html,文件叫,index.html,,不想叫这个名字,可以改,minify:,collapseWhitespace:true,/,把生成的,index.html,文件的内容的没用空格去掉,减少空间,hash:true,/,为了更好的,cache,,可以在文件名后加个,hash,。,bundle.js?f3cdsd6d56a565d7d565,),;,31,2025/4/29 周二,六,.webpack,插件,html-webpack-plugin,html-webpack-plugin,肯定还有更多的用法和选项,这个只能根据需要慢慢探究了。,先说这么多,32,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,什么是,loader,?,官方:,loader,用于对模块的源代码进行转换。,loader,可以使你在,import,或,加载,模块时预处理文件。因此,,loader,类似于其他构建工具中“任务,(task)”,,并提供了处理前端构建步骤的强大方法。,loader,可以将文件从不同的语言(如,TypeScript,)转换为,JavaScript,,或将内联图像转换为,data URL,。,loader,甚至允许你直接在,JavaScript,模块中,import CSS,文件!,33,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,WebPack,简单的说就是它能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中。它作为一个打包工具,在前端工程化浪潮中,起到了中流砥柱的作用。,那,webpack,其中非常重要的一环就是,能够对加载的资源文件,进行一些处理。比如把,less,、,sass,文件编译成,css,文件,负责这个处理过程的,就是,webpack,的,loader,。,34,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,loader,用于对模块的源代码进行转换。,loader,可以使你在,import,或,加载,模块时预处理文件。因此,,loader,类似于其他构建工具中“任务,(task)”,,并提供了处理前端构建步骤的强大方法。,说白了,就是,loader,类似于,task,,能够处理文件,比如把,Scss,转成,CSS,,,TypeScript,转成,JavaScript,等,举个稍微复杂的例子,,vue-loader,,它官网介绍如下:,vue-loader,是一个,Webpack,的,loader,,可以将指定格式编写的,Vue,组件转换为,JavaScript,模块。,Vue,组件默认分成三部分,,、,和,,我们可以把一个组件要有的,html,,,js,,,css,写在一个组件文件中,而,vue-loader,,会帮助我们去处理这个,vue,组件,把其中的,html,,,js,,,css,分别编译处理,最终打包成一个模块。,35,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,1.,实例:,用,css-loader,和,style-loader,处理,CSS,先准备好内容。,app/app.css,body,background:pink;,app/main.js,import css from./app.css;,const greeter=require(./Greeter.js);,/document.querySelector(body).appendChild(greeter(),console.log(document.querySelector(body).appendChild(greeter();,如果你现在运行,npm run dev,或,webpack,命令,就会出现提示错误,36,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,默认情况下,,webpack,处理不了,CSS,的东西。,我们来处理这个问题。,$npm install-save-dev css-loader style-loader,37,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,webpack.config.js,var HtmlWebpackPlugin=require(html-webpack-plugin);,module.exports=,entry:./app/main.js,output:,path:_dirname+/dist,filename:bundle.js,plugins:new HtmlWebpackPlugin(,template:./dist/index.html,filename:index.html,minify:,collapseWhitespace:true,hash:true,),module:,rules:,test:/.css$/,use:style-loader,css-loader,;,38,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,2.,实例:,用,sass-loader,把,SASS,编译成,CSS,https:/www.sass.hk/docs/,把,app/app.css,改名为,app/app.scss,app/app.scss,body,background:pink;,p,color:red;,app/index.html,Hello World,hello world,39,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,app/main.js,引用更改为,import css from./app.scss;,安装(中间可能要下载二进制包,要耐心等待),$npm install sass-loader node-sass-save-dev/,未安装,$npm install sass-loader node-sass/,正确安装,更改,webpack.config.js,文件内容,module,:,rules:,test:/.scss$/,use:style-loader,css-loader,sass-loader,40,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,3.,实例:,用,extract-text-webpack-plugin,把,CSS,分离成文件,有时候我们要把,SASS,或,CSS,处理好后,放到一个,CSS,文件中,用这个插件就可以实现。,$npm install-save-dev extract-text-webpack-plugin,41,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,webpack.config.js,var HtmlWebpackPlugin=require(html-webpack-plugin);,const ExtractTextPlugin=require(extract-text-webpack-plugin);,plugins:new HtmlWebpackPlugin(,template:./src/index.html,filename:index.html,minify:,collapseWhitespace:true,hash:true,),new ExtractTextPlugin(style.css),module:,rules:,test:/.scss$/,use:ExtractTextPlugin.extract(,fallback:style-loader,/resolve-url-loader may be chained before sass-loader if necessary,use:css-loader,sass-loader,),;,42,2025/4/29 周二,七,.,使用,loader,处理,CSS,和,Sass,执行,npm install-save-dev extract-text-webpack-plugin,之后,执行,npm run dev,如果还报错(,UnhandledPromiseRejectionWarning:Unhandled promise rejection.,),需要执行,npm install extract-text-webpack-pluginnext,来解决这个版本不同导致的,BUG,43,2025/4/29 周二,我们之前使用,webpack-d-watch,来在开发环境下编译静态文件,但是这个功能,完全可以用,webpack-dev-server,来代替。,除此之外,,webpack-dev-server,还有其他的功能,比如在本地上开启服务,打开浏览器等。,这节我们主要来简单体验一下,webpack-dev-server,的功能。,八,.,初识,webpack-dev-server,44,2025/4/29 周二,八,.,初识,webpack-dev-server,#,先全局安装,$npm install-g webpack-dev-server,$npm install-save-dev webpack-dev-server,然后运行命令:,$webpack-dev-server,45,2025/4/29 周二,八,.,初识,webpack-dev-server,默认是运行在,8080,端口,这个我们可以改。,我们还可以配置一运行,webpack-dev-server,的时候就自动打开浏览器。,webpack.config.js,var HtmlWebpackPlugin=require(html-webpack-plugin);,const ExtractTextPlugin=require(extract-text-webpack-plugin);,module.exports=,entry:./src/app.js,.,devServer:,port:9000,open:true,.,;,46,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,一般这个插件是配合,webpack-p,这条命令来使用,就是说在为生产环境编译文件的时候,先把,build,或,dist(,就是放生产环境用的文件,),目录里的文件先清除干净,再生成新的。,47,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,1.,webpack.config.js,const path=require(path),module.exports=,entry:,bundle:./app/main.js,output:,path:path.resolve(_dirname,public),filename:name.chunkhash.js,.,;,$,webpack-p,48,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,49,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,你再把,app/main.js,改改内容,然后再执行,webpack-p,。,再多运行几次,生成的带,hash,的,bundle.js,文件就会很多。,这些带,hash,的,bundle.js,只有最新的才有用,其他的都没用,我们要在,build,之前把它们全清空,这真是,clean-webpack-plugin,发挥的作用。,2.,开始使用,clean-webpack-plugin,首先来安装。,$npm i clean-webpack-plugin-save-dev,50,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,webpack.config.js,const CleanWebpackPlugin=require(clean-webpack-plugin);,let pathsToClean=,public,module.exports=,plugins:,new CleanWebpackPlugin(pathsToClean),.,new ExtractTextPlugin(style.css),.,;,51,2025/4/29 周二,九,.,用,clean-webpack-plugin,来清除文件,52,2025/4/29 周二,十,.,配置多个,HTML,文件,之前我们只写了一个,html,文件,就是,src/index.html,,但是有时候我们是需要多个的,这个时候,怎么办呢?,转 六,.webpack,插件,html-webpack-plugin,53,2025/4/29 周二,十,.,配置多个,HTML,文件,webpack.config.js,plugins:,new HtmlWebpackPlugin(,title:hello world,filename:index.html,template:./app/index.html,),new HtmlWebpackPlugin(,title:web pack,filename:contact.html,template:./app/contact.html,),54,2025/4/29 周二,十,.,配置多个,HTML,文件,App/contact.html,Contact,Contact page,App/contact.js,console.log(hi from contact js),55,2025/4/29 周二,十,.,配置多个,HTML,文件,contact.html,使用的,js,和,css,跟,index.html,是一模一样的,如果我要让,contact.html,使用跟,index.html,不同的,js,,如何做呢?(只要保证,js,不同,,css,也会不同的,因为,css,也是由,js,里,import,的嘛,),56,2025/4/29 周二,十,.,配置多个,HTML,文件,entry:,bundle:./app/main.js,/,这行是新增的。,contact:./app/contact.js,output:,path:_dirname+/dist,plugins:new HtmlWebpackPlugin(,template:./app/index.html,filename:index.html,/,这行是新增的。,excludeChunks:contact,),new HtmlWebpackPlugin(,template:./app/contact.html,filename:contact.html,/,这行是新增的。,chunks:contact,),57,2025/4/29 周二,十一,.,58,2025/4/29 周二,59,2025/4/29 周二,60,2025/4/29 周二,61,2025/4/29 周二,62,2025/4/29 周二,63,2025/4/29 周二,64,2025/4/29 周二,65,2025/4/29 周二,66,2025/4/29 周二,67,2025/4/29 周二,68,2025/4/29 周二,69,2025/4/29 周二,
展开阅读全文