今天介绍一篇关于工程搭建的文章。主要介绍不用cli脚手架搭建一套前端工程,因为每个公司不是用脚手架工具安装一下就能进行开发了,很多时候都是对工程有一定的定制需求,你没有深入的去了解cli脚手架的话,可能会很吃力,所以这块还是需要有一定的深入了解的,内容也不是太复杂,但是你需要掌握一些vue、webpack、nodejs的简单的基本概念和认识,也挺适合初级者阅读,我们学前端的小伙伴其实都知道,前端的工程搭建不像后端,后端有一套非常健全的ide开发工具,我们不管做什么样子的项目,企业级应用的话,用j2ee;web工程用javaweb等等一些定制化的工程,都有一套。对于开发这来说,其实注重的是服务器的搭建,接口的定制,开发的调试,业务的实现。但对于前端来说,我们其实并没有太多这样的ide工具(忽略webstorm,因为没怎么使用过,才肤浅地这么认为),但是也不排除未来会出现,我们还是一起期待吧。所以在这些工具出来之前,我们前端的同学还是得学会自己来搭一套前端工程。
接下来我来告诉大家为什么要搭建这么一个工程。可能很多小伙伴都有类似的经历,没有经历过得朋友不用担心,未来你能理解的,也会遇到,那有过一些开发项目经验的同学应该会发现身边的同事大概有两种发展方向。一种是做业务开发的,一种是偏向于技术框架的。前者更注重业务的实现,我们知道一个项目百分之八十的时间都是用在实现业务逻辑方面,做多了我们其实会发现,这种开发的工作对我们的挑战其实并不是太大,每个公司的业务逻辑都不一样,复杂度也并不是太高,所以技术提升这一方面,其实是有一定限制的。但是存在即合理,注重这块开发的同学其实可以往管理的角度来发展,也不失为一种方向。但是对技术有一定要求的同学来说,我觉得更需要往后者的方向靠拢。前面也说了业务代码很多都是拷贝粘贴,对基本功有一定的要求,如果想从技术方向去提升自己的价值,我个人建议还是往前端工程化的方向去发展。从工程的搭建,模块化的设计,api的定制,请求的封装,本地开发模式的建立,工程上线的部署等等,这些都需要非常的熟悉。这样一来不管你到哪家公司,做什么样的项目,有一套这样的技术储备作为解决方案,你会很吃香。当然如果后期向往管理的方向发展,也是可以的,这个时候的你对技术的掌握能力,能帮助你更能准确地评估出开发的工作量,掌控项目的开发周期,比前者更准确地估算项目人力成本的预算以及开发过程中遇到的技术难题和风险点,这是非常实用的,内容较多,小白们建议某个周末早上读完。
所以仁者见仁,每个人有每个人的发展方向,不一定按照这样的模式去丰富自己,这只是依照个人的一些实际经验做出来的总结。好了闲话不扯太多了,我们进入正式进入主题吧。
okay,我们先来配置我们的项目,首先我们新建一个文件夹,用vscode打开,这里开发工具的选择依照自己的喜好来。
我们通过快捷键 ‘ctrl + ·’,也就是esc下面的小点,打开终端,我们先来用 npm init 来初始化项目,因为这里是演示demo,我全部使用的默认,大家实验的时候直接敲回车就行了。
Microsoft Windows [版本 6.1 .7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。 E:\vue实战\vue_web>npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. package name: (vue_web) version: ( 1.0 .0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to E:\vue实战\vue_web\ package. json: { "name": "vue_web", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this OK? (yes) yes E:\vue实战\vue_web>
这个时候细心的同学会发发现我们目录下面多一个叫package.json的文件,这个文件就是我们项目的配置文件。
好,我们先来安装一下包,因为我们用到了vue以及webpack,所以我们需要将这两个依赖包安装一下,除了这些呢,还有段落标题中的vue-loader,这个就是为了用webpack加载.vue文件,并将它编译成浏览器能认识的js文件,我们先来执行这样的指令,注:我们这里是demo,所以这里就不区分是否是dev-dependency了。(详情可以参考https://www.cnblogs.com/ayseeing/p/4128612.html)
npm i webpack vue vue-loader
E:\vue实战\vue_web>npm i webpack vue vue-loader npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN vue- loader@ 15.5 .1 requires a peer of css- loader@* but none is installed. You must install peer dependencies yourself. npm WARN vue_web@ 1.0 .0 No description npm WARN vue_web@ 1.0 .0 No repository field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@ 1.2 .4 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@ 1.2 .4: wanted { "os": "darwin", "arch": "any"} (current: { "os": "win32", "arch": "x64"}) + webpack@ 4.28 .4 + vue@ 2.5 .22 + vue- loader@ 15.5 .1 added 350 packages from 286 contributors and audited 4195 packages in 153.368s found 0 vulnerabilities E:\vue实战\vue_web>
安装完成之后会出现一些waring,大家可以可看出来这个warning其实就是告诉我们在安装vue-loader的同事必须要安装css-loader,这里我们想它继续安装完成就可以了。
npm WARN vue_web@1.0.0 No description
npm WARN vue_web@1.0.0 No repository field.
这两个是我们项目初始化的时候由于都是回车回车,缺少一些描述,无需关心。
npm WARN optional SKIPPING OPTIONAL
npm WARN notsup SKIPPING OPTIONAL
这两个是告诉我们项目初始化时候哪些是可选择安装的,哪些是可以不安装的,这里我们也无需,继续执行
npm i css-loader
E:\vue实战\vue_web> npm i css-loader npm WARN vue_web@ 1.0 .0 No description npm WARN vue_web@ 1.0 .0 No repository field. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@ 1.2 .4 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@ 1.2 .4: wanted { "os": "darwin", "arch": "any"} (current: { "os": "win32", "arch": "x64"}) + css-loader@ 2.1 .0 added 18 packages from 10 contributors and audited 4301 packages in 34.711s found 0 vulnerabilities E:\vue实战\vue_web>
好,到这里,我们项目的大概的初始化工作就完成了。接下来我们就基于这样的目录,填充一下更丰富的细节。
我们在工程目录下新建一个src文件夹用来存放源文件,并新建一个app.vue的文件:
app.vue文件代码:
<template> <div id="text"> {{text}} </div> </template> <script> export default { data() { return { text: 'lrxu' } } } </script> <style> #text { color: red; } </style>
大家都知道,浏览器其实只能够识别一些简单的文件,像js,css,html,img,font,但是如何让浏览器识别vue文件呢?
到这其实我们应该有一些认知了,webpack其实就是一个帮我们打包的工具。接下来我们在工程目录下新建一个webpack.config.js文件。
接下来我们在新建的webpack.config.js里面做文章。我们知道webpack是用来打包的工具,我们工程总得有个入口文件,让浏览器去访问,让webpack去打包并输出。所以这个时候我们的事情来了,配置webpack的入口和出口。
在src目录下新建一个index.js的文件作文工程的入口文件。
然后我们在index.js里面写一些内容,代码中我都做了注释,大家应该一眼就能看懂
index.js:
//这是工程的入口文件 import Vue from 'vue'; import App from './app.vue'; const root = document.createElement( 'div') document.body.appendChild(root) //mount就是讲我们的App挂载到root这样一个根节点中去 new Vue({ render: (h) => h(App) }).$mount(root)
我们这时候发现,浏览器要想运行这段代码,那是不可能的,因为浏览器不认识vue,更不认识new Vue,所以webpack要登场了。我们在webpack.config.js里配上entry入口和out出口,表示webpack文件会将将entry路径下的文件,打包到out的路径,
具体如下:
webpack.config.js:
const path = require( "path");//nodejs里面的基本包,用来处理路径 //__dirname表示文件相对于工程的路径 module.exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') } }
这里代码就不多说了,都有注释,这里卖个关子,也是经常会发生的场景,就是这里的join和resolve这两个函数的用法和区别,最好去官网看一下说明,直通车https://webpack.js.org/,英文不好的同学可以去中文官网学习都是可以的,没有关系的,看不懂的时候我也会去看中文文档。
好上面的代码就是做了这样一件事,将src下的index.js文件以js的形式打包到dist目录下的bundle.js中去。大家有疑问了,这两个目录我还没有新建呢!没有关系out属性中定义的路径如果没有的话,webpack会自动创建的,我们需要做的是就是新建src目录并添加index.js文件。那这个动作我们已经新建完成了,不记得的同学返回文章内容再看看。
这时候我们打开package.json文件添加一句:
"build": "webpack --config webpack.config.js"
很多有经验的同学应该都用过npm run build 这句话,这里添加的这个指令,就是我们在终端输入npm run build之后webpack帮我们干的一些事情,那我们这里呢这句的意思就是webpack去帮我们执行我们新建的webpack.config.js文件。注意这里我们使用webpack来执行指令,同样也可以在终端执行这段指令,但是我们要清楚在终端直接执行build后面的指令会出现一个问题,如我们在终端执行该指令,意味着使用的是全局的webpack,但是我们写在package.json文件下的话,意味着执行工程下面的局部wepackage,全局和局部可能会版本不一样,所以为了避免不必要的麻烦,我们在package.json文件下执行,也就是说使用的局部的webpack来打包。
好到这里,我们编译打包输入输出的相关配置已经完成,我们先执行一下:npm run build。可能有经验的小伙伴会发现还有一些配置没有完成,没关系,我们一步步来,带着错误把问题一个一个解决。
E:\vue实战\vue_web>npm run build > vue_web @1. 0.0 build E:\vue实战\vue_web > webpack --config webpack.config.js One CLI for webpack must be installed. These are recommended choices, delivered as separate packages: - webpack-cli ( https: //github.com/webpack/webpack-cli) The original webpack full-featured CLI. We will use "npm" to install the CLI via "npm install -D". Do you want to install 'webpack-cli' (yes/no): yes
由于我使用的是webpack4,所以这里必须要安装一下cli。这里有人就问了,哎呀不是不用cli的嘛,怎么要安装这个包。如果你有这样的想法,证明你有自己用过cli搭建过vue项目框架的一些经验。我们知道用cli脚手架搭建出来的项目结构应该是这样的:
该图来源于网络,我们这里安装这个cli包是因为webpack4之后强制要求安装的,但是我们并没有通过该工具来初始化整个工程,所以建出来的目录也是不一样的,所以大家仔细想想就明白了。好了,接下来直接yes就可以,安装完成之后,再执行一下 npm run build,有些不需要再执行,但没有关系,反正都会报错:
E:\vue实战\vue_web>npm run build > vue_web@ 1.0 .0 build E:\vue实战\vue_web > webpack --config webpack.config.js Hash: 057884840cecb3060636 Version: webpack 4.28 .4 Time: 5481ms Built at: 2019 -01 -14 13: 31: 11 1 asset Entrypoint main = bundle.js [ 0] (webpack) /buildin/global.js 472 bytes { 0} [built] [ 1] . /src/app.vue 184 bytes { 0} [built] [failed] [ 1 error] [ 3] . /src/index.js 233 bytes { 0} [built] + 4 hidden modules WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https: //webpack.js.org/concepts/mode/ ERROR in . /src/app.vue 1: 0 Module parse failed: Unexpected token ( 1: 0) You may need an appropriate loader to handle this file type. > <template> | <div id= "text"> | {{text}} @ . /src/index.js 3: 0 -28 10: 19 -22 npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! vue_web@ 1.0 .0 build: `webpack --config webpack.config.js` npm ERR! Exit status 2 npm ERR! npm ERR! Failed at the vue_web@ 1.0 .0 build script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\Administrator\AppData\Roaming\npm-cache\_logs\ 2019 -01 -14T05_31_12_291Z-debug.log E:\vue实战\vue_web>
切图看一下
这个错误呢就是告诉你我们,需要为app.vue这个文件声明一个loader,因为webpack只支持js类型的文件,像这种vue文件是不支持的,所以我们要使用一些工具,来帮助它认识超出它理解范畴的语法。接下来便到了我们的module环节。
由于webpack存在这样的一个限制,我们就需要来使用一些工具,我们在webpack.config.js里添加module配置项
webpack.config.js:
const path = require( "path"); //nodejs里面的基本包,用来处理路径 //__dirname表示文件相对于工程的路径 module. exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, module: { rules: [ { //通过vue-loader来识别以vue结尾的文件 test: /.vue$/, loader: 'vue-loader' } ] } }
好添加完成之后,再次执行 npm run build 指令。
好,又报错了,这时候的错误是告诉我使用vue-loader的方式不正确。Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的,所以我们这里再来修改一下。这里会使用plugin属性,不了解的同学可以先跳过,也可以去官网查看一下这个属性的作用,这里我就先不介绍了。我们在package.config.js文件中添加VueLoaderPlugin,代码如下:
const path = require( "path"); //nodejs里面的基本包,用来处理路径 const VueLoaderPlugin = require( 'vue-loader/lib/plugin'); //__dirname表示文件相对于工程的路径 module. exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, plugins: [ // make sure to include the plugin for the magic new VueLoaderPlugin() ], mode: 'none', module: { rules: [ { //通过vue-loader来识别以vue结尾的文件 test: /.vue$/, loader: 'vue-loader' } ] } }
再次执行一次 npm run build 还会报错,哈哈,到这有人会抱怨啦,是不是没玩没了啦。不用担心,保证这个问题解决完之后就可以啦。先看错误信息
不知道大家还记不记的我在app.vue文件中用“style标签嵌入”的方的式写css样式了:
但是webpack并没有处理css的能力,所以我们还需要在moudle添加rules配置项,如下
const path = require( "path"); //nodejs里面的基本包,用来处理路径 const VueLoaderPlugin = require( 'vue-loader/lib/plugin'); //__dirname表示文件相对于工程的路径 module. exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, plugins: [ // make sure to include the plugin for the magic new VueLoaderPlugin() ], mode: 'none', module: { rules: [ { //通过vue-loader来识别以vue结尾的文件 test: /.vue$/, loader: 'vue-loader' }, { //通过vue-loader来识别以vue结尾的文件 test: /.css$/, //css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明 use: [ 'style-loader', //接受潜在页面内部的style标签的文件。 'css-loader' ] } ] } }
好了,别忘了执行一下 npm i style-loader,因为之前没有安装过这个包,否则又要报错了。这部分属于配置静态资源的部分了,本来是要放到下一章节来讲的,但是这里遇到了问题,就先介绍了。我们最后执行一下 npm run build指令,不出意外的话,应该是这样的:
我们也看到了确实生成了dist/bundle.js文件,我们可以进去简单看一下:
我们确实看到一些我们写下来的文件资源,被打包到js文件中之后的代码。好到这里,我们项目配置的部分就到这里了。接下来,我会给大家介绍一下如何在项目中使用webpack配置静态资源。
上一张我们详细使用了webpack加载并打包vue文件,以及最后处理的css文件,就针对静态资源这块,我们可以稍微更详细地了解一下。
好,在上一张的末尾,我们接触了css样式加载,我们稍微复习一下,大家也可以回头在巩固一下。
这里用了use属性而不是loader属性,是因为我们处理css文件的方式有多种,所以这里出多种方式的css加载需要用到use属性,所以这里用到了use,style-loader也就是处理html文件内部的style标签内的css样式,也就是我们俗称的内联,css-loader处理的是从文件外部引入的css文件,这里大家简单了解一下。
然后我们的图片怎么做呢?我相信大家举一反三的能力比我强多了,我们加载图片用到的loader叫‘url-loader’,它的作用是将我们的图片转换成一个base64的字串存放于我们打包生成的js里面,而不是重新生成一个文件。对于一些小的文件,几kb的文件可以帮助我们减少过多的http请求。那么url-loader其实封装了我们的file-loader,file-loader其实是将文件进行处理后换个名字存放于另一个地方。那么我们先看下配置:
const path = require( "path"); //nodejs里面的基本包,用来处理路径 const VueLoaderPlugin = require( 'vue-loader/lib/plugin'); //__dirname表示文件相对于工程的路径 module. exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, plugins: [ // make sure to include the plugin for the magic new VueLoaderPlugin() ], mode: 'none', module: { rules: [ { //通过vue-loader来识别以vue结尾的文件,正则表达式中的点需要转义 test: /\.vue$/, loader: 'vue-loader' }, { //通过vue-loader来识别以vue结尾的文件 test: /\.css$/, //css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明 use: [ 'style-loader', //接受潜在页面内部的style标签的文件。 'css-loader' ] }, { //处理图片文件 test: /\.(gif|jpg|jpeg|png|svg)$/ , use: [ { loader: 'url-loader', options: { limit: 1024, name: '[name]-aaa.[ext]' } }, ] } ] } }
我们这里同样使用的use属性,不同的是数组里面使用的对象,因为我们对图片还需要进行一些更细化的配置,像图片的大小(limit),文件名称(name)有时都是需要进行配置的,所以这里使用了对象。下面呢,我们将使用到的loader安装一下。
npm i url-loader file-loader
那些warn我前面也有提到过,如果不记得的同学,可以回顾一下。我们安装完成了之后,所有的包是可以通过import来使用的。
接下来我们介绍一下图片的loader,新建一个assets目录,然后放几张图片进去,并同时新建一个styles目录新建一个test样式
图片大家可以自行下载,css就简单的给body设置了样式:
test.css:
body{ color: red; background-image: url( '../images/logo.png'); }
并且将我们项目的入口文件添加几行代码:
//这是工程的入口文件 import Vue from 'vue'; import App from './app.vue'; import './assets/styles/test.css'; import './assets/images/vue.png' const root = document.createElement( 'div') document.body.appendChild(root) //mount就是讲我们的App挂载到root这样一个根节点中去 new Vue({ render: (h) => h(App) }).$mount(root)
好,我们现在执行一下npm run build 指令,可以看到webpack将图片打包成base64字串存放于js中,并且重新生成了新的文件
我们再来看一下bundle.js
我们在看找一下这个数字21在哪。
大家可以看到,如我们所预料的一样,生成了新的文件。这时候细心的同学人提出疑问啦?不是说生成的base64字串嘛,怎么存的是个文件名?其实大家不必惊讶,我们之前在配置里设置的limit的属性不知道大家还记不记得。
配置信息的参数“limit=1024”表示将所有小于1kb的图片都转为base64形式,而我们的图片的大小:
都超过了1KB,webpack表示不是我的锅,我不背...
我们将limit稍微改大一点设置20k,按照理论小一点的图片应该会被处理成base64的图片。我们再次执行一下npm run build,结果果真如我们所想:
我们小一点的图片的logo.png被编译成了base64字串,是不是很神奇呢!
我们经常听到过 sass less style-component这些比较火热的css预处理器,那这些我们webpack能不能处理呢?答案是肯定的。
这里我给大家推荐一款预处理器-stylus,大家多多少少听过或者使用过。我们新增一个配置项,注意:我们这里新增了stylus-loader,所以需要将这个安装包执安装,由于stylus-loader这个包依赖于stylus这个包,所以我们这里执行安装指令:
npm i stylus-loader stylus
webpack.config.js代码:
const path = require( "path"); //nodejs里面的基本包,用来处理路径 const VueLoaderPlugin = require( 'vue-loader/lib/plugin'); //__dirname表示文件相对于工程的路径 module. exports ={ entry: path.join(__dirname, 'src/index.js'), output: { filename: 'bundle.js', path: path.join(__dirname, 'dist') }, plugins: [ // make sure to include the plugin for the magic new VueLoaderPlugin() ], mode: 'none', module: { rules: [ { //通过vue-loader来识别以vue结尾的文件,正则表达式中的点需要转义 test: /\.vue$/, loader: 'vue-loader' }, { //通过vue-loader来识别以vue结尾的文件 test: /\.css$/, //css的处理方式不同,有嵌入在页面style标签里的,有从外部文件引入的,我们这里用use来声明 use: [ 'style-loader', //接受潜在页面内部的style标签的文件。 'css-loader' ] }, { test: /\.styl$/, use: [ 'style-loader', 'css-loader', 'stylus-loader' ] }, { //处理图片文件 test: /\.(gif|jpg|jpeg|png|svg)$/ , use: [ { loader: 'url-loader', options: { limit: 1024 * 20, //将所有小于1kb的图片都转为base64形式 name: '[name]-aaa.[ext]' } }, ] } ] } }
我们新建一个styls,我们想要在vscode中使用stylus需要安装一个插件:
安装完成之后,重新启动就可以了。我们新建的styl文件如下:
代码:
test-stylus-.styl
body font-size 20px
这种写法是不是看上去落落大方,透露一股简约风范。我们再将这个styl文件在入口文件中引用进来。
入口文件 index.js
//这是工程的入口文件 import Vue from 'vue'; import App from './app.vue'; import './assets/styles/test.css'; import './assets/styles/test-stylus.styl'; import './assets/images/vue.png'; const root = document.createElement( 'div') document.body.appendChild(root) //mount就是讲我们的App挂载到root这样一个根节点中去 new Vue({ render: (h) => h(App) }).$mount(root)
接着我们就可以编译一下,继续执行npm run build 指令编译
编译完成之后我们又可以看到 bundle.js文件里有又多了一个模块,我们刚刚用stylus写的font-size也出现再里面,其实我们可以发现我们在stylus中没写大括号,冒号,分号,webpack却把它编译成了标准的css。是不是有觉得很神奇呀!那其实我们对于一些热门的css预处理器的使用也有了参考,如果不会使用的建议大家到github上去搜,去参考,我相信这聪明的你们来说就是‘洒洒水啦’。
好,到这里我们使用webpack配置项目的静态资源和css预处理器已经介绍完了,接下来我会介绍,我们在开发过程中使用的插件和工具来帮助我们提高开发效率。
这个包是咱们在开发环境用的包处理工具,我们这里先install这个包。npm i webpack-dev-server
这部分内容是在换了个网络环境下完成的,因为移动的网速度不快,这里使用了cnpm来安装。使用方式就是在package.json文件里添加:
"scripts": { "test": "echo \" Error: no test specified\ " && exit 1", "build": "webpack --config webpack.config.js", "dev": "webpack-dev-server --config webpack.config.js" }
这里添加完dev指令后需要到webpack.config.js下修改一部分内容来专门适应我们的开发环境。
首先我们需要添加target属性,将其设置为‘web’,由于我们使用的是浏览器编译平台,所以这里设置为web,这也是webpack这个属性的默认设置,所以写不写无所谓。更多的target属性值我这里给他家提供腾讯云的解释:https://cloud.tencent.com/developer/section/1477500,大家可以去参考一下,也可去官网上去查阅。
接下来我们需要区分全局的一个环境,很容易就想到需设置一个全局的环境变量来做区分控制,我们在build指令后面添加代码
注意这里的指令在windows平台可能不适合,会需要这样写:
我们如果不想区分不同系统,写一套代码来适应多个系统,我们这里就使用到了 cross-env,我们在指令前面添加cross-env
当然这个包也是需要安装的,执行
cnpm i cross-env
最后我们还需要给dev下的指令配置一个变量值,用来区分两套环境
"scripts": { "test": "echo \" Error: no test specified\ " && exit 1", "build": "cross-env NODE_ENV=production webpack --config webpack.config.js", "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js" }
这里完成之后我们就可以在webpack.config.js文件里面进行判断了。
我们现在文件下新建一个变量
const isDev = process.env.NODE_ENV === 'development';
我们启动时设置的脚本变量都是可以通过process.env这个对象来获取的。更多关于process.env的内容可以到https://webpack.docschina.org/guides/environment-variables/读阅。
这里我们判断如果是dev环境的话,我们就给webpack.config.js添加一些配置。
if(isDev){ config.devServer = { port: 8000, host: '0.0.0.0', overlay: { erros: true, } } }
首先我们给devServer属性添加一个port,因为我们新建的是一个服务,所以肯定要一个端口,接下来我们配置host,这里使用‘0.0.0.0’也是有好处的。这样可以通过127.0.0.1(本地默认地址)来进行访问,同时还可以在别人的机器上来访问,因为如果设置成‘localhost’的话通过ip是不能访问的。这里大家了解一下,更多相关derserver内容可以去这里参考:https://www.webpackjs.com/configuration/dev-server/。overlay属性是在我们编译的过程中能够让任何的错误都显示到网页上面。最后我们加完了这些基础的配置之后回过头来发现,我们好像配置的只是js、css、img文件,没有html页面去容纳它们。这个时候我们用到一个webpack的一个插件html-webpack-plugin,我们照样来安装一下它:
cnpm i html-webpack-plugin
并且在webpack.config.js文件的头部将它require进来,同时在plugin中新建。这里推荐一篇博客关于html-webpack-plugin的,大家可以参阅一下http://www.cnblogs.com/wonyun/p/6030090.html。
到这里我们基本的配置就完成了,最后需要了解一下webpack.DefinePlugin,我们在代码中的plugin里添加:
plugins: [ // make sure to include the plugin for the magic new webpack.DefinePlugin({ 'process.env': { NODE_ENV: isDev ? '"development"' : '"production"' } }), new VueLoaderPlugin(), new HTMLPlugin() ],
这里我们用到了webpack,所以需要将 webpack 这个变量引用进来。
好,这部分代码有什么用呢?第一,在使用了这个plugin之后我们可以在编译的过程以及我们开发的过程中通过process.env来调用NODE_ENV来进行判断;第二,我们在不同的环境下来区分打包,在开发环境我们更多提高了开发效率,使用了很多错误提示等一些工具,但是生产环境没必要去用,一方面会增加文件的大小,另一方面会降低代码的运行效率,所以我们需要根据不同的环境,编译执行的动作也不一样,就需要利用这个来判断,说句高端一点,就是将环境变量进行选择性替换;第三,我们注意到这里使用的单引号里接双引号的方式,这里是由于webpack在转移我们代码的时候,如果不写双引号,会是这样:
process.env.NODE_ENV = development,我们知道这其实是将development赋值给它,这里会提示找不到变量,所以这里需要单引号里面接双引号。更多细节请移驾https://www.css88.com/doc/webpack2/plugins/define-plugin/
说到这里,理论上我们已经完成的本地开发环境的编译,通过npm run dev就可以进行编译,我们来试验一下。
执行:npm run dev
这里在浏览器里面输入localhost:8000会出现:
说明我们webpack-dev-server已经启动成功了。
这里我们再介绍一些devserver其他的一些配置。