前端框架Vue自学之webpack(四)

摘要:
win系统下cmd命令:npminstallwebpack@3.6.0-g)。在终端直接执行webpack命令,使用的是全局安装的webpack。这就涉及到webpack的配置文件。首先,我们在根目录下创建webpack.config.js文件,然后通过CommonJS导出一个对象,定义入口和出口。当我们在终端输入webpack,执行命令时,它会自动找到webpack.config.js文件,读取入口和出口。

终极目标:掌握和使用Vue(全家桶:Core+Vue-router+Vuex)

本博客目的:记录Vue学习的进度和心得(webpack)

内容:学习和使用webpack。为学习Vue CLI做准备。

正文:

webpack

一、webpack

1、认识webpack

本质上来说,webpack是一个现代的JavaScript应用的静态模块打包工具。模块和打包。

前端的模块化:之前在我的博客也提到,目前一些模块规范有:AMD,CMD,CommonJS,ES6的module。在ES6之前,我们想要进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发,并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。而webpack其中一个核心就是让我们可以进行模块化开发,并且会帮助我们处理模块间的依赖关系。而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等再webpack中都可以被当做模块来使用。这就是webpack中模块化的概念。

打包:将webpack中的各种资源模块进行打包合成一个或者多个包(Bundle),并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将SCSS转(CSS扩展语言)成CSS,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。

2、与grunt/gulp的对比(现在一般用webpack比较多)

grunt/gulp的核心是task。可以配置一系列的task,并且定义task要处理的事务(比如ES6,TS转化等),之后让grunt/gulp来依次执行这些task,并且让整个流程自动化。所以grunt/gulp也被称为前端自动化任务管理工具。

如果我们的工程模块依赖非常简单,甚至是没有用到模块化的概念,只需要进行简单的合并、压缩,就使用grunt/gulp即可。但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更强大的webpack了。

3、webpack安装

webpack为了可以正常运行,必须依赖Node环境。Node环境为了可以正常的执行很多代码,必须其中包含各种各样的包, 也需要包管理工具npm工具。

安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm。Node.js可以在官网下载:Node.js(要大于8.9版本),全局安装webpack(简易学习时,先用3.6.0版本,因为vue cli依赖这个版本。win系统下cmd命令:npm install webpack@3.6.0 -g)。后续可能需要我们局部安装webpack(--save-dev是开发时依赖,项目打包后不需要继续使用的。)

为什么全局安装后,还需要局部安装?在终端直接执行webpack命令,使用的是全局安装的webpack。当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack。

4、webpack的基本使用

一般在项目的根目录下,会创建两个文件夹:src和dist。src放置源码(打开的东西),dist(distribution发布)放置把源码打包的东西,最终发布。src一般会有main.js或者是index.js,然后根目录下会创建一个index.html文件(这个文件也是最后要放到dist文件夹内)。

由于之前讨论过,现在在src里面的js代码都是按照模块化的方式去写(CommonJS、Module等)。开发中,我们可能会创建多个js文件,假如说main.js(相当于一个入口文件)是依赖于某个mathUntils.js,那么意味着传统的做法是要在index.html下用script标签先引入mathUntils.js再引入main.js。但是按照模块化的思想,我们可以将mathUntils.js写成一个模块,然后用CommonJS的方法引入其进入main.js。然而,在index.html只使用这个main.js,是不行的,因为浏览器不认识main.js中的CommonJS代码(会报错说require,module未定义)。这个时候,可以使用webpack对js文件进行打包,打包出来一个浏览器能识别的js文件,然后在index.html引用这个js文件。

所以在开发中,我们都在通过CommonJS方式写js代码,用webpack自动会帮我们处理这些JS代码模块间的依赖关系,最后生成一个浏览器识别的js文件。在下面的例子,我们可以发现我们只需打包main.js这个入口文件,而不是打包main.js和mathUntils.js两个文件。因为webpack会自动帮我们在main.js查看是否有依赖其他文件,并且自动处理各种模块间的依赖,这点在大型项目里面非常有效,因为在一个大的开发项目中,有各种JS文件,各种相互依赖的模块,我们只用关心入口文件main.js即可。

总结:以后我们在开发中,只需要在src文件下开发,使用CommonJS或者是ES6的module模块化规范都行(甚至可以混合使用都行),最后我们通过使用webpack模块打包,最后在index.html代码引入打包后的文件即可。(当然,最后我们还有把index.html放入到dist文件内,后续再说)

举例:

前端框架Vue自学之webpack(四)第1张(我们的工作目录)  前端框架Vue自学之webpack(四)第2张(index.html)

前端框架Vue自学之webpack(四)第3张(main.js)前端框架Vue自学之webpack(四)第4张(mathUtils.js)

这个时候直接引入main.js的index.html会报错。

所以,我们要使用webpack,即在终端输入webpack ./src/main.js ./dist/bundle.js(如果webpack没有权限,得用管理员的身份打开Windows PowerShell授权)

前端框架Vue自学之webpack(四)第5张

这样就在dist目录下生成了js文件(里面相当于webpack自动帮我们定义解析了浏览器能识别的CommonJS的命令)

前端框架Vue自学之webpack(四)第6张

然后在index.html只引入webpack打包生成的bundle.js文件,最后就可以在浏览器得到正确结果显示了。

前端框架Vue自学之webpack(四)第7张(index.html引入bundle.js)

前端框架Vue自学之webpack(四)第8张(浏览器控制台显示正确结果)

5、webpack.config.js配置和package.json配置

有时候,我们直接在终端输入一个webpack(而不是长串的webpack ./src/main.js ./dist/bundle.js命令),直接将src文件夹中的文件就模块打包生成包文件进dist文件夹中。这就涉及到webpack的配置文件。

首先,我们在根目录下创建webpack.config.js文件(名字不可改),然后通过CommonJS导出一个对象,定义入口和出口。当我们在终端输入webpack,执行命令时,它会自动找到webpack.config.js文件,读取入口和出口。

注意的是,我们在定义入口和出口时,把src/main.js路径作为入口,而出口不是写成dist/bundle.js,而是写为一个对象,里面包含path(有要求)和filename(bundle.js)。这个path,里面输入绝对地址,但不要复制文件夹地址的方式,而是用动态获取路径,即使用node语法,引入node中名为path的包。

我们项目中并没有node的包,所以得在终端输入npm init(npm init -y 全部选择yes,但注意这样得全英文路径),初始化node包,起包名,版本号,描述,入口点(index.js或者随便写此时还用不上),等等初始化项目,最后选择OK。现在就在我们根目录下生成了package.json文件,里面就是我们要依赖的Node环境的文件,告诉我们一些信息。如果package.json还依赖一些东西,我们还需要在终端输入npm install,其会帮助我们的package.json安装一些需要的东西(生成了一个package-lock.json文件)。

最后在终端执行webpack,就可以自动打包生成在dist目录下的bundle.js文件了。

前端框架Vue自学之webpack(四)第9张(webpack.config.js)

前端框架Vue自学之webpack(四)第10张(终端执行webpack)

6、但是,一般在开发中,我们很少在终端输入webpack,而是输入npm run build,通过npm进行构建打包。

因为webpack.config.js名称是写死的,在开发中,我们可能需要用别的名字比较方便。并且,后续学习可以知道使用局部的webpack的命令行也很长,很麻烦。所以我们需要将其都映射在npm run XXX这样的格式的命令。

我们在package.json里面找到一个scripts的选项,在初始化的时候,里面有test对象。当我们在终端输入 npm run test,就会输出该对象。所以,我们在选项下面,定义一个build("build":"webpack")。这样在终端输入npm run build就相当于输入webpack执行(相当于一次映射)。

注意,这种定义方式是优先在本地执行,例如先找本地安装的webpack,由于目前我们没有在本地安装webpack,所以它会找全局安装的webpack,所以执行了全局的webpack。在开发项目中,一般用的都是本地的webpack。而且假如本地用的webpack版本和全局用的webpack版本不同,这个时候这种方式就可以让我们指定使用项目开发中的本地版本的webpack,这样就不会选错版本而导致配置出错的问题了。

7、本地(局部)安装webpack

依赖分为:开发时依赖和运行时依赖。在开发阶段才用到webpack,但在打包完,给服务器,运行时就用不到webpack(也就是说webpack是一个打包后就不用的东西)。我们后面使用的Vue是运行时依赖,要写入dependencies 节点。

所以在本地安装webpack用命令:npm install webpack@3.6.0 --save-dev(3.6.0是版本号,-save-dev 的意思是将模块安装到项目目录下,并在package文件的devDependencies(开发时依赖)节点写入依赖。devDependencies 节点下的模块是我们只开发时需要用的。如果是开发和运行阶段都要用,则写入dependencies 节点,用--save后缀)。package.json里面会写入devDependencies对象,里面是我们3.6.0版本的webpack。

补充:我们要在自己的编译器受理管理员权限,例如我用的是VSCode,要在程序的兼容性中给予管理员权限。在我们自己的练习中,可能会有两个warn,就是说没有description和repository,也就是说缺少项目的基本描述文件和仓库字段,一般团队合作时会用到,比如readme和git仓库,设置了就不会有警报了,当然也可以在package.json中添加"private": true选项表示这是私人的,这样也不会有警报。 可能还会有两个optional和notsup的警告,因为这个fsevents依赖是个可选的依赖包,只有项目运行环境是mac OS时才会使用,所以在windows和linux下会报这个warn,无关紧要。

注意,只要我们是在终端执行的命令(不管是编译器下的还是WIN的CMD下的),如输入webpack,都是在全局使用webpack。但是如果使用npm run build(刚刚在我们package.json定义的"build":"package"),就可以优先在本地搜索webpack,从而本地执行webpack(即执行的是从项目内的node_modules文件夹内的webpack)。

8、webpack中使用CSS文件的配置(loader)

之前用webpack模块打包了用模块化规范写的JS文件,但在实际开发中,我们还会写CSS文件,我们也想将其当做模块,去引用。类似的,可能还有其他类型的文件需要引入(例如图片,ES6转ES5,TS转ES,.jsx或.vue转JS文件等)。对于webpack本身的能力来说,这些转换时不支持的,那么就需要给webpack扩展对应的loader就可以了。

loader是webpack中一个非常核心的概念。loader的使用步骤:通过npm安装需要使用的loader;在webpack.config.js中的module关键字下进行配置。大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。

通常的文件组织方式是在src文件夹里面创建一个js文件夹,里面放置除了main.js的js文件,main.js是入口文件放在src内的最外层,其他js文件就放到js文件夹里面。

我们在src文件夹里创建css文件夹,并创建一些css文件。我们不能在index.html里直接引入这些CSS文件,一个个引入太麻烦了。我们可以将css文件看做是一个模块,将它们打包进bundle.js文件里面。但注意webpack是根据入口文件进行找依赖,然后打包,如果入口文件假设没有依赖这个CSS文件,那么直接打包是没有引入这个CSS文件的。

所以,我们在main.js里面写入对这个CSS依赖。例如直接加入require('./css/normal.css'),然后运行npm run build进行打包,这个时候,你会发现有错误,上面说需要一个合适的loader去处理这个文件。

这个时候我们可以去webpack官网,找这个loader。进入官网,点文档,点右上角有个Loaders选项,根据需求选择loader。例如我们现在需要的是css样式的loader,选择样式(style),选择css-loader,里面会告诉我们如何使用css-loader。使用loader步骤如之前所述:安装和配置。按照说明,先在终端执行npm install --save-dev css-loader。然后在webpack.config.js中创建module关键字并进行配置(复制官网的规则粘贴即可)。最后,我们再使用npm run build进行打包。(我们会发现这个规则,第一部分是一个正则表达式,用于匹配相关文件;第二部分用来引用loader的)

前端框架Vue自学之webpack(四)第11张

补充1:官网的css-loader规则里除了使用了css-loader(我们之前已经安装),还使用了style-loader(我们还没安装)。 假如我们只使用了css-loader(删除style-loader),在打包构建后,index.html展示不出我们写的normal.css的效果。原因是因为css-loader只负责将css文件进行加载,不负责解析。所以还是得补全写入style-loader选项,因为我们没有这个loader,所以得安装这个style-loader(回到官网,找到style-loader,安装和配置),style-loader的作用是将模块的导出作为样式添加到DOM中。最后,在点开index.html文件,确实展示了我们写的CSS文件了。

补充2:使用了多个loader时,其顺序是很重要的。在上例,由于我们使用了多个loader,按照逻辑,我们应该是先把CSS加载,然后在把样式添加到DOM中。但由于webpack规定,使用多个loader的顺序是从右向左的。所以得写成use:['style-loader','css-loader']。如果交换,则会报错。

9、less文件的处理(webpack下)

CSS预处理器是 CSS 语言的超集,比CSS更丰满。CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

CSS预处理器语音,常用的有Sass(SCSS)、LESS、Stylus等。例如less可以@变量名:值来定义一个变量,然后在样式代码中使用(类似编程思想)。

webpack也是可以处理这些文件的,以less(.less文件)为例。 首先,在CSS创建一个less文件,文件名为special.less。然后在main.js里面引用(依赖)这个less文件(require('./css/special.less')),此时,如果就打包的话就会报错,还是因为没有合适的loader处理less文件。同样地,打开官网,找到less-loader,安装与配置。注意,我们会发现官网除了安装了less-loader(负责加载)还安装了一个less包(工具),less包就是用来解析less代码,转换为CSS文件。此外,在配置的时候,我们只复制添加rules对象(包含test和use的对象)而不是整个module。接着在按照之前说的,打包,点击index.html查看即可。

10、图片文件的处理

开发中,我们可能还需要别的一些资源文件,例如图片,视频等。

webpack也是可以处理这些资源文件的,我们以图片文件举例。

首先,在src文件夹中创建图片img文件夹,里面放些图片,举例放一张joker.jpg。然后,我们在CSS文件夹下的normal.css的body引入这个图片(background:url('../img/joker.jpg');)。这次,打包时,发现报错,还是说没有一个合适的loader处理图片。同样地,上webpack官网,找文件的loader,因为我们是通过url引入的图片,应该使用url-loader。接着安装和配置。最后打包,即可使用。

注意,我们在配置图片url-loader时,有个options对象,里面有个limit属性,值为一个数值(字节数),当加载图片,(图片大小)小于limit时,会加载url-loader,将图片编译成base64字符串形式。如果图片大小大于这个limit时,会报错,说找不到file-loader模块,此时如果要加载比limit大的图片时,我们只需安装file-loader。file-loader只安装不用配置(因为要用的是url-loader)。此时,打包,没有报错,在dist文件夹内生成了一张32位哈希值(防止图片名重复)的图片,但是运行index.html代码时,发现没有加载图片,打开控制台,发现提示没有找到图片(项目根目录下),(如果我们把哈希值名的图片放在项目根目录就可以显示,但是实际中我们应该把图片打包进bundle.js里面),也就是说我们希望在dist的目录路径搜索应用的图片而不是在根目录下。此时,需要我们配置一个路径。

通过修改webpack.config.js文件,在output里面添加publicPath(publicePath:'dist/'),以后我们每次用到url就会在前面拼接这个路径,即dist/(相当于在根目录下添加这个目录)。这样我们再次进行打包,此时,index.html能正确显示我们的图片了。

注意,如果我们最终把index.html打包到dist文件夹时(还没说到,暂时不管),publicPath就不需要了。

此外,在真实开发中,我们可能对打包的图片名字有一定要求。比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复。所以,我们在webpack.config.js中的url-loader规则内的options内,添加name属性(name:'img/[name].[hash:8].[ext]'),意思是img:文件要打包到的文件夹。name:有中括号,获取原来图片的名字。hash:8:防止图片名称重复,使用8位的hash值,仍然是中括号内。ext:使用图片原来的扩展名,仍然是中括号内。这样之后,再打包,就可以在dist文件夹下创建img文件夹,并且有名为joker.112e36c8.jpg的图片,最终的index.html也是可以展示出来。

11、ES6转ES5的Babel

之前的用webpack打包的js文件,发现ES6语法并没有转成ES5语法,那么意味着可能一些对ES6还不支持的浏览器没有办法很好地运行我们的代码(例如我们之前打包生成的bundle.js里面含有const的ES6语法)。所以我们希望使用webpack打包时,顺带着把ES6转成ES5。

如果我们想要把ES6转成ES5,那么使用babel。而在webpack中,我们直接使用babel对应的loader就可以了。终端输入npm install --save-dev babel-loader@7 babel-core babel-preset-es2015(7版本,还需babel-core和babel-preset-2015。官网是配置-env,后面我们会学),接着在webpack.config.js进行配置(这个loader对应的rules),这个rules里面多个exclude:/(node_modules|bower_components)/((exclude排除,不包括),它的意思是只需转换src文件夹里面js代码,由于之前本地安装了一些包依赖,这些包放在node_modules文件夹内,里面有一些ES6语法写的模块,但是不需要转换为ES5语法。此外,由于我们是配置babel-preset-es2015(与官网不同,官网是配置-env),所以我们得在loader的options的presets:['@babel/preset-env']修改为presets:['es2015']。接着打包,此时,打包文件都是ES5语法了(例如此时我们的bundle.js的const转为了ES5的var)。

12、使用Vue的配置过程

为了能在我们src文件夹里使用vue相关的东西,必须进行配置。后续项目中,我们会使用vue,js进行开发,而且会以特殊的文件来组织vue的组件。所以,我们得学习如何在webpack环境中集成vue.js。之前我们使用vue.js都是把该文件通过script标签引入,而不是模块化管理的方式。我们希望以模块化思想使用vue.js,即使用npm安装的方式,把vue.js安装到node_modules里,把vue当成一个模块,即可以在代码中通过import Vue from 'vue'即可(这样vue文件是通过在node_modules文件夹路径搜索,因为node_modules里对应模块是用export default Vue)。

我们希望在项目中使用vue.js,那么必要需要对其有依赖,所以先进行安装。终端输入npm install vue --save(vue是运行时依赖,打包和使用bundle.js都要用)。注意,在main.js使用vue的时候,先引用vue,并在对应的index.html写入对应代码,然后打包。

可能这样的index.html运行时会报错,说runtime-only版本vue的模板不可靠。这是因为vue在构建最终发布版本的时候,构建了两类版本:runtime-only和runtime-compiler。runtime-only要求代码中,不可以有任何的template,因为这个版本没有编译template的代码。runtime-compiler中可以有template,因为有complier可以用于编译template。

所以当我们遇到runtime-only这个问题时,需要对webpack进行配置。我们可以先去vue.js的官网,搜索webpack,里面提及希望使用完整版vue时,则需要在打包工具里配置一个别名。在webpack.config.js中加入resolve选项,填入alias:{'vue$':'vue/dist/vue.esm.js'},意思是在我们引入vue时,先引用这个vue路径下的/vue.esm.js(vue的一个发布版本,里面包含着runtime-compiler,默认下,使用的是vue.runtime.js版本)。这个时候再重新打包构建,就发现已经解决了runtime-only报错的问题。

13、创建Vue时template和el关系

之前我们使用的都是单页面网络应用SPA(single page web application),多个页面的话,后续学习是通过前端路由(vue-router)跳转的,一般只有一个html代码(index.html),一般是不修改,固定的,当做一个模板。所以在真实开发中,不会把大量的关于vue的代码写到html代码中(只需给元素简单配个id,为在main.js中的vue组件等对应起来)。所以,通常是把在用到vue的html代码写在main.js中用template属性中(注意template一般得给一个根元素节点)。

在vue源码中,可以知道上面这种把html代码写在template中,在编译时,vue会复制template的html代码,替换el绑定的元素中。这样的好处就是不用每次手动修改html代码(index.html)了。

14、Vue的终极使用方案

但是在main.js里面写大量的template,也会显得非常冗余。所以,我们考虑使用组件。

首先,我们看一下基本思路。首先,我们把原来写到Vue实例的template内容,data内容和methods内容,写到外面,在外面定义一个对象(例如名为App),该对象包含原来的template属性,data属性(注意,组件中的data属性要写成函数形式,返回数据对象的形式)和methods属性。然后vue实例对象,只剩下el属性。接着,在vue实例里,使用components属性注册这个对象为组件(即components:{App}),并在vue实例里使用template属性,把这个组件作为模板内容(即template:`<App/>`,<App/>相当于<App></App>)。同样地,最后也是可以正常执行html文件。

为了更进一步地简化,我们在src文件夹里面创建vue文件夹,并创建一个js文件,我们把刚刚那个组件对象的代码剪切到这个vue文件夹下的s文件并用模块的方法导出(例如exportdefault XX对象),然后在原来main.js的对应部分删除,只需导入这个模块(import ‘App’ from './vue./app.js')就可以一样使用这个组件了。

【.vue文件的封装处理】但是仍存在一个问题,就是在我们vue下的js文件中,模板与JS代码没有分离。所以,我们可以在vue文件夹中创建一个.vue文件(如果使用VScode编译器,会提示安装vetur插件,才能解析我们的.vue文件),.vue文件就是一个vue组件文件,里面包含三大块:template块,script块和style块。然后,我们把之前在.js写的代码内容,对应的写到template块,script块(注意,这个script块中,是通过exportdefault 开头,表示导出这个对象,里面要有name属性(一般与文件名一样))和style块(可以定义我们在template块中的html代码的一些样式)。然后,我们在原来的main.js中引入这个组件(例如importAppfrom'./vue/App.vue'),而不是先前的那个js文件。

此时,回想起之前我们用webpack加载除了js以外的文件,如css文件,会需要一个合适的loader。同样地,当我们加载vue文件时,也是需要一个loader,所以得安装与配置。在这里,我们需要vue-loader(负责加载vue)和vue-template-complier(vue的模板编译),即在终端输入npm install vue-loader vue-template-compiler --save-dev(我们在加载完编译完就不用了,所以是开发时依赖),接着就是webpack.config.js中配置,在rules下添加{test:/.vue$/,use:{loader:'vue-loader',}},此时会报错,说vue-loader缺少一个插件(plugin),由于vue-loader版本(在package.json中查看)在14版本开始,需要额外配置插件。如果不想额外配置插件,我们在package.json修改vue-loader的版本为13.0.0,然后在终端输入npm install(重新根据我们的package.json的版本要求,更新依赖)。最后在重新打包,这个时候就不会报错了。而且在index.html中也没有出错,和我们之前用vue文件夹的js文件的方法结果是等效的。

以后的我们是想组件化开发(一般组件名是首字母大写),所以同样的,我们是可以在vue文件夹里面创建别的组件(例如Cpn.vue),然后可以在我们之前写的App.vue里面中使用,即在script块中先引入该组件,在原组件对象内注册该组件;template块使用该组件。最后打包,点开index.html,还是可以使用到该组件。

所以以后,我们可以创建一个自定义组件(例如我们的App.vue),其可以引用别的组件(别的组件也是可以引用别的组件),从而形成了一个组件树(其根就是我们自定义组件),每个组件都是独立的,这就是组件化开发。

补充1:对于我们的VScode编译器,每次创建vue文件(vue组件)时,都要写template标签,script标签和style标签,很麻烦,我们就可以借助VScode的代码模板的功能,依次点击菜单栏 -文件 - 首选项 - 用户代码片段,然后搜索vue,然后添加我们对应的组件模板,保存。下次创建使用时,直接输入vue+tab键,即可快速创建代码模板了。

补充2:如果想简写引用文件的后缀名,如importAppfrom'./vue/App.vue'简写为importAppfrom'./vue/App',需要我们在webpack.config.js中的resolve中添加extension选项(extensions:['.vue'])。

15、plugin的使用(BannerPlugin的使用)

plugin是插件的意思,通常是用于对某些现有的架构进行扩展。webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。  

loader和plugin区别。loader主要用于转换某些类型的模块或加载,它是一个转换器或加载器。plugin是插件,它是对webpack本身的扩展,是一个扩展器。

plugin的使用过程(安装与配置):首先,通过npm安全需要使用的plugins(某些webpack已经内置的插件不需要安装)。接着就是在webpack.config.js中的plugins中配置插件。

下面就简单介绍几个webpack的插件。

添加版权的plugin。插件名字为BannerPlugin,属于webpack自带的插件,用于为打包的文件添加版权声明(或者一些说明信息)。

具体步骤是:由于该插件是webpack自带的,所以不需要npm安装。所以直接在webpack.config.js里面配置,首先,引入webpack包(constwebpack=require('webpack')),然后在module.exports对象中,配置Plugins选项(plugins:[newwebpack.BannerPlugin('最终版权归ABC所有')])。最后打包,可以发现,在打包后的bundle.js里面的第一行有我们的版权信息(/*!最终版权归ABC所有*/)。

16、HtmlWebpackPlugin的使用

之前我们使用的index.html是在根目录下的,在真实发布项目时,我们最终是希望将其也打包进dist文件夹内(让打包发布的文件都在一起),最后发布的版本应该是这个dist文件夹内html文件。 这个时候就需要用到HTMLWebpackPlugin插件。

HTMLWebpackPlugin插件可以自动生成一个index.html文件(可以指定模板来生成),并且可以将打包的js文件,自动通过script标签插入到body中。

这个HTMLWebpackPlugin插件不是webpack自带的,所以得先安装。终端输入npm install html-webpack-plugin --save-dev(开发时依赖)。接着在webpack.config.js配置plugins,首先还是先导入插件(constHtmlWebpackPlugin=require('html-webpack-plugin')),修改plugins选项(plugins:[newHtmlWebpackPlugin() ])。然后打包,结果发现dist目录下生成了index.html文件,并且自动引入了bundle.js文件。此外,由于之前我们需要在body里面创建一个div块并且id为app,即我们vue实例所绑定的html元素,所以我们可以给它一个模板。在原来根目录下的index.html去除之前用script标签引入bundle.js(其实就是把这个index.html当做打包html的模板),接着在plugins:[newHtmlWebpackPlugin()]的括号里面添加这个index.html文件作为模板(plugins:[newHtmlWebpackPlugin({template:'index.html'}) )。最后打包,点开dist文件夹内的index.html,没有问题。(注意,如果之前是按照在webpack.config.js里面配置一个路径,需要去掉(//publicPath:'dist/'),因为此时的index.html是在dist目录下了。)

17、UglifyjsWebapckPlugin的使用

在项目发布之前,我们必然需要对js等文件进行压缩处理。这里,我们就对打包的js文件进行压缩(原理是通过去除空格,修改变量名为短长度变量名,删掉注释等)。这个使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致。

首先安装,在终端输入npm install uglifyjs-webpack-plugin@1.1.1 --save-dev。接着配置,在webpack.config.js中先导入插件(constUglifyjswebpack=require('uglifyjs-webpack-plugin')),然后添加plugins(newUglifyjswebpack())。最后打包,生成的bundle.js是压缩的了,里面没有什么格式,“紧紧靠在一起”,“像丑化了一样”(所以才是uglifyjs嘛)。但是不影响index.html的正常展示。

18、dev-server搭建本地服务器

webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架(可以服务于我们某个文件夹,实时监听其中代码的改变,根据配置,在内存里(非文件夹里)生成一些文件,待输入npm run build构建时,才真正把文件放入文件夹磁盘里),可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

使用前,先安装。终端输入:npm install --save-dev webpack-dev-server@2.9.3(开发时依赖,并且版本是对应于我们的webpack版本,也是脚手架CLI2的版本) 。接着就是配置,在webpack.config.js中的module.exports中添加devServer对象(根据设定的选项,指定服务的文件夹,是否需要实时监听,端口号,H5history模式否等),这里我们配置基础简单的模式:devServer:{contentBase:'./dist',inline:true}(服务的是dist文件夹,需要实时监听)。接着就是在本地跑服务,先在package.json中配置scripts脚本"dev":"webpack-dev-server"(千万别输入webpack-dev-server,因为在终端输入这个都是在全局上搜索执行的,而我们是装是本地的(没有带-g))。最后,在终端输入npm run dev 运行我们的服务,此时,我们点开终端输出的网络地址http://localhost:8080/,实时再修改代码,保存时,该网页也是实时显示最新的东西。这个就相当于是一个本地测试。

当我们测试满意了,就可以执行npm run build 进行打包构建。

此外,由于上述方法需要手动点开本地服务连接,如果我们希望一运行本地服务就打开浏览器,可以改为"dev":"webpack-dev-server --open"。

19、配置文件的分离

在开发阶段,其实我们是不需要Uglifyjswebpack插件压缩我们的js代码(真正发布阶段才用),因为不好调试。在发布阶段,devServer是不需要的。也就是说,在webpack中,我们希望有些插件或配置是想在打包时使用,运行发布的时候不使用,或者是反过来。这个时候需要我们对它们进行分离。

首先,我们在根目录下创建build文件夹,里面创建base.config.js,prod.config.js,dev.config.js,分别代表着基本公共使用的配置代码,生产产品的配置代码和开发调试的配置代码。例如我们之前使用到的大部分配置是放在base.config.js(除了丑化js压缩插件和本地服务devServer),dev.config.js放入本地服务devServer配置,prod.config.js放入丑化js压缩插件配置。
也就是说最终编译生产时,我们需要的配置文件是base.config.js和prod.config.js。在开发调试的时候,需要的配置文件是base.config.js和dev.config.js。
由于我们需要一些工具将其合并。使用webpack-merge(merge合并)插件,首先安装,在终端输入npm install webpack-merge --save-dev。然后在prod.config.js引入webpack.merge,并且引入base.config.js,把模块导出写成如下图所示:
前端框架Vue自学之webpack(四)第12张
同理,dev.config.js也是类似处理: 前端框架Vue自学之webpack(四)第13张

现在,是把原来一个webpack.config.js文件分离为三个文件,实现了生产配置与开发配置的分离。

此时,可以把原来的webpack.config.js文件删除。并且在package.json中修改scripts脚本(因为原来的webpack配置文件变成了build文件夹下的文件,所以是需要重新指定配置对象),修改build和dev,

"build":"webpack--config./build/prod.config.js",
"dev":"webpack-dev-server--open--config./build/dev.config.js"
注意,由于此时的配置文件是在build文件夹下的(之前的配置文件是在根目录下的),最后我们打包是想把文件打包进根目录下的dist文件夹内,所以需要修改模块打包的输出路径,例如把path:path.resolve(__dirname,'dist')改成path:path.resolve(__dirname,'../dist')(即上一级目录(根目录)的dist文件夹下),否则打包生成的会是在build文件夹的dist文件夹内。
此时指定了生产配置和开发配置。最后像之前一样,终端输入npm run build就可以生产版本配置,npm run dev可以打开本地服务进行开发调试。

webpack部分终于结束了,可以回归我们的vueCLI脚手架的“正题”了:)

(在我下一个博客里:前端框架Vue自学之Vue CLI(五)

免责声明:文章转载自《前端框架Vue自学之webpack(四)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#-获取字符的GBK编码值Node 之URL模块下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux下的磁盘加密方法

Linux下的磁盘加密方法 转载时请注明出处和作者联系方式作者联系方式:李先静 <xianjimli at hotmail dot com> 随着智能手机的计算能力和存储能力的提高,手机中将会存放越来越多的私有数据,这些数据的泄密可能造成严重后果。手机信息安全一直是我们的重点之一,对于一些重要的功能我们要求鉴权后才能使用,但这只能挡住初级的黑...

(转)react 项目构建

原文:https://segmentfault.com/a/1190000016342792 写在前面 每次构建react项目的时候都会配置一大堆东西,时间久了就会忘记怎么配置。为了方便自己记忆也为了其他开发者在构建react应用时能够快速开发,故作此记录。 本项目基于 create-react-app 脚手架进行配置。主要配置了一些项目开发中常用的方法,...

使用asmfd绑定磁盘

1.停止crs,配置asmfd[root@lxtrac04 bin]# ./asmcmd afd_configureAFD-627: AFD distribution files found.AFD-634: Removing previous AFD installation.AFD-635: Previous AFD components succes...

Create Ubuntu DEB package from a Qt application

PackagingGuide/QtApplication - Ubuntu Wiki QtApplication Create Ubuntu DEB package from a Qt application The following instructions describe how to create an Ubuntu .deb packag...

从零开始的野路子React/Node(9)Antd + multer实现文件上传

最近心血来潮,打算自己捣腾个web app来练练手(虽然大概率会半路弃坑……),其中有一部分是关于文件上传的,在实现的过程中遇到了一些坑,于是打算把血泪教训都记录下来。 前端的部分采用了Antd,不得不说真是香,至少比我司内部的前端库香了1000倍……事半功倍。后端部分则主要通过multer来实现,目测应该是一种比较通用的做法? 1、捯饬前端 首先我们新建...

Echarts(曲线图)

写在前面: 最近项目中用到了Echarts做趋势图,博主通过万能的度娘研究了一下。Echarts字段的使用基本都写在代码注释里了,这是博主的第一篇博客,如果哪里写的不好望大家见谅,最后希望本篇博客对大家有一些帮助。 1. 下载Echarts.js包 使用Echarts需要先下载Echarts.js包,大家可以从Echarts官网下载, 或者可以从博主提供的...