六、Webpack详解学习笔记——webpack的安装、起步、配置、loader的使用、webpack中配置Vue、plugin的使用、搭建本地服务器、webpack配置的分离

一、认识webpack

  • 什么是webpack?
    这个webpack还真不是一两句话可以说清楚的。
  • 我们先看看官方的解释:
    At its core, webpack is a static module bundler for modern JavaScript applications.
  • 从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具。
    但是它是什么呢?用概念解释概念,还是不清晰。
    我们从两个点来解释上面这句话:模块 和 打包
    在这里插入图片描述
  1. 前端模块化:
  • 在前面学习中,我已经用了大量的篇幅解释了为什么前端需要模块化。
  • 而且我也提到了目前使用前端模块化的一些方案:AMD、CMD、CommonJS、ES6。
  • 在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
  • 并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。
  • 而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
  • 而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用(在后续我们会看到)。
    这就是webpack中模块化的概念。
  1. 打包如何理解呢?
  • 理解了webpack可以帮助我们进行模块化,并且处理模块间的各种复杂关系后,打包的概念就非常好理解了。
  • 就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。
  • 并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。

但是打包的操作似乎grunt/gulp也可以帮助我们完成,它们有什么不同呢?
和grunt/gulp的对比:

grunt/gulp的核心是Task
我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css)
之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。 所以grunt/gulp也被称为前端自动化任务管理工具。

我们来看一个gulp的task
下面的task就是将src下面的所有js文件转成ES5的语法。
并且最终输出到dist文件夹中。
在这里插入图片描述
什么时候用grunt/gulp呢?

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

所以,grunt/gulp和webpack有什么不同呢?

  • grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。
  • webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能。

二、webpack的安装

  1. 安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm

  2. 查看自己的node版本:
    在这里插入图片描述

  3. 全局安装webpack(这里我先指定版本号3.6.0,因为vue cli2依赖该版本)
    在这里插入图片描述

  4. 局部安装webpack(后续才需要)
    --save-dev是开发时依赖,项目打包后不需要继续使用的。
    在这里插入图片描述

为什么全局安装后,还需要局部安装呢?

  • 在终端直接执行webpack命令,使用的全局安装的webpack
  • 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack

三、webpack的起步

3.1 准备工作

我们创建如下文件和文件夹:
在这里插入图片描述
文件和文件夹解析:

  1. dist文件夹:用于存放之后打包的文件
  2. src文件夹:用于存放我们写的源文件
  3. main.js:项目的入口文件。具体内容查看下面详情。
  4. mathUtils.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。具体内容查看下面的详情。
  5. index.html:浏览器打开展示的首页html
  6. package.json:通过npm init生成的,npm包管理的文件(暂时没有用上,后面才会用上)

mathUtils.js文件中的代码:
在这里插入图片描述

main.js文件中的代码:
在这里插入图片描述

3.2 js文件的打包

现在的js文件中使用了模块化的方式进行开发,他们可以直接使用吗?
不可以。
因为如果直接在index.html引入这两个js文件,浏览器并不识别其中的模块化代码。
另外,在真实项目中当有许多这样的js文件时,我们一个个引用非常麻烦,并且后期非常不方便对它们进行管理。

我们应该怎么做呢?

  • 使用webpack工具,对多个js文件进行打包。
  • 我们知道,webpack就是一个模块化的打包工具,所以它支持我们代码中写模块化,可以对模块化的代码进行处理。(如何处理的,待会儿在原理中,我会讲解)
  • 另外,如果在处理完所有模块之间的关系后,将多个js打包到一个js文件中,引入时就变得非常方便了。

OK,如何打包呢?
使用webpack的指令即可
在这里插入图片描述
注意:如果webpack是4.0.x版本以上,使用webpack ./src/main.js -o ./dist/bundle.js --mode development

在这里插入图片描述

3.3 使用打包后的文件

打包后会在dist文件下,生成一个bundle.js文件
在这里插入图片描述

文件内容有些复杂,这里暂时先不看,后续再进行分析。
bundle.js文件,是webpack处理了项目直接文件依赖后生成的一个js文件,我们只需要将这个js文件在index.html中引入即可
在这里插入图片描述
在这里插入图片描述

四、webpack的配置

4.1 入口和出口

我们考虑一下,如果每次使用webpack的命令都需要写上入口和出口作为参数,就非常麻烦,有没有一种方法可以将这两个参数写到配置中,在运行时,直接读取呢?
当然可以,就是创建一个webpack.config.js文件
在这里插入图片描述

4.2 局部安装webpack

目前,我们使用的webpack是全局的webpack,如果我们想使用局部来打包呢?

  • 因为一个项目往往依赖特定的webpack版本,全局的版本可能很这个项目的webpack版本不一致,导出打包出现问题。
  • 所以通常一个项目,都有自己局部的webpack。
  1. 第一步,项目中需要安装自己局部的webpack
    这里我们让局部安装webpack3.6.0
    Vue CLI3中已经升级到webpack4,但是它将配置文件隐藏了起来,所以查看起来不是很方便。
    在这里插入图片描述
    第二步,通过.\node_modules\.bin\webpack启动webpack打包
    在这里插入图片描述

4.3 package.json中定义启动

但是,每次执行都敲这么一长串有没有觉得不方便呢?
OK,我们可以在package.json的scripts中定义自己的执行脚本。
在这里插入图片描述
在这里插入图片描述

package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。

  • 首先,会寻找本地的node_modules/.bin路径中对应的命令。
  • 如果没有找到,会去全局的环境变量中寻找。

如何执行我们的build指令呢?
在这里插入图片描述

五、loader的使用

5.1 什么是loader?

loader是webpack中一个非常核心的概念。

webpack用来做什么呢?

  • 在我们之前的实例中,我们主要是用webpack来处理我们写的js代码,并且webpack会自动处理js之间相关的依赖。
  • 但是,在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。
  • 对于webpack本身的能力来说,对于这些转化是不支持的。

那怎么办呢?给webpack扩展对应的loader就可以啦。
loader使用过程:

  1. 步骤一:通过npm安装需要使用的loader
  2. 步骤二:在webpack.config.js中的modules关键字下进行配置

大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。

5.2 css文件处理 - 准备工作

项目开发过程中,我们必然需要添加很多的样式,而样式我们往往写到一个单独的文件中。
在src目录中,创建一个css文件,其中创建一个normal.css文件。
我们也可以重新组织文件的目录结构,将零散的js文件放在一个js文件夹中。
在这里插入图片描述
normal.css中的代码非常简单,就是将body设置为red:
在这里插入图片描述
但是,这个时候normal.css中的样式会生效吗?

  • 当然不会,因为我们压根就没有引用它。
  • webpack也不可能找到它,因为我们只有一个入口,webpack会从入口开始查找其他依赖的文件。

在入口文件中引用:
在这里插入图片描述
重新打包,会出现如下错误:
在这里插入图片描述
这个错误告诉我们:加载normal.css文件必须有对应的loader。

5.3 css文件处理 – css-loader

在webpack的官方中,我们可以找到如下关于样式的loader使用方法:
在这里插入图片描述

按照官方配置webpack.config.js文件
注意:配置中有一个style-loader,我们并不知道它是什么,所以可以暂时不进行配置。

重新打包项目:
但是,运行index.html,你会发现样式并没有生效。
原因是css-loader只负责加载css文件,但是并不负责将css具体样式嵌入到文档中。
这个时候,我们还需要一个style-loader帮助我们处理。

5.4 css文件处理 – style-loader

在这里插入图片描述

我们来安装style-loader
在这里插入图片描述
在这里插入图片描述

注意:style-loader需要放在css-loader的前面。
疑惑:
不对吧?按照我们的逻辑,在处理css文件过程中,应该是css-loader先加载css文件,再由style-loader来进行进一步的处理,为什么会将style-loader放在前面呢?

答案:
这次因为webpack在读取使用的loader的过程中,是按照从右向左的顺序读取的。

在浏览器中打开index.html页面:
在这里插入图片描述

5.5 less文件处理 – 准备工作

如果我们希望在项目中使用less、scss、stylus来写样式,webpack是否可以帮助我们处理呢?
我们这里以less为例,其他也是一样的。
我们还是先创建一个less文件,依然放在css文件夹中
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
出现了报错信息,提示我们需要安装less-loader

5.6 less文件处理 – less-loader

继续在官方中查找,我们会找到less-loader相关的使用说明
在这里插入图片描述
首先,还是需要安装对应的loader
注意:我们这里还安装了less,因为webpack会使用less对less文件进行编译
在这里插入图片描述
在这里插入图片描述

其次,修改对应的配置文件
添加一个rules选项,用于处理.less文件
在这里插入图片描述
执行npm run build命令,启动webpack重新打包项目:
在这里插入图片描述
注意:这里如果运行失败了,检查下less-loader的版本,版本过高可能就会失败!
在这里插入图片描述
在main.js文件中加入一行代码:
在这里插入图片描述
再次执行npm run build命令,启动webpack重新打包项目:
在这里插入图片描述
在浏览器中打开index.html文件:
在这里插入图片描述

5.7 图片文件处理 – 资源准备阶段

  • 首先,我们在项目中加入两张图片:
    一张较小的图片test01.jpg(小于8kb),一张较大的图片test02.jpeg(大于8kb)
    待会儿我们会针对这两张图片进行不同的处理
  • 我们先考虑在css样式中引用图片的情况,所以我更改了normal.css中的样式:
    在这里插入图片描述

如果我们现在直接打包,执行npm run build命令,会出现如下报错信息:
在这里插入图片描述

5.8 图片文件处理 – url-loader

访问官方文档:
在这里插入图片描述

图片处理,我们使用url-loader来处理,依然先安装url-loader
在这里插入图片描述
在这里插入图片描述

修改webpack.config.js配置文件:
在这里插入图片描述
再次执行npm run build命令,启动webpack重新打包项目:
在这里插入图片描述
注意:
此处需要注意url-loader的版本,版本太高可能会出现虽然运行没有报错,但是index.html页面中无法显示图片,版本号如下所示,修改完之后,执行npm install重新安装,再执行npm run build命令重新打包
在这里插入图片描述
再次打包,运行index.html,就会发现我们的背景图片选出了出来。
而仔细观察,你会发现背景图是通过base64显示出来的
OK,这也是limit属性的作用,当图片小于29kb时,对图片进行base64编码
在这里插入图片描述
在这里插入图片描述
那么问题来了,如果大于29kb呢?我们将background的图片改成beijing.png
这次因为大于29kb的图片,会通过file-loader进行处理,但是我们的项目中并没有file-loader

5.9 图片文件处理 – file-loader

执行npm run builde出现如下报错提示信息:
在这里插入图片描述
在这里插入图片描述
所以,我们需要安装file-loader,执行npm install file-loader --save-dev命令,安装file-loader:
在这里插入图片描述

在这里插入图片描述
执行npm run build命令,就会发现dist文件夹下多了一个图片文件:在这里插入图片描述

在这里插入图片描述

用浏览器打开index.html文件发现,背景图片仍然无法正常显示:
在这里插入图片描述

  • 但是,我们发现图片并没有显示出来,这是因为图片使用的路径不正确
  • 默认情况下,webpack会将生成的路径直接返回给使用者
  • 但是,我们整个程序是打包在dist文件夹下的,所以这里我们需要在路径下再添加一个dist/

当把background属性的url中的路径前面加上./dist/之后,发现背景图片可以正常显示了,说明背景图片一开始之所以无法显示,是路径错了
在这里插入图片描述

解决方案如下:
在webpack.config.js文件中添加publicPath:
在这里插入图片描述
然后重新执行npm run build命令,再次打开index.html页面,背景图片就能正常显示了!
在这里插入图片描述

5.10 图片文件处理 – 修改文件名称

我们发现webpack自动帮助我们生成一个非常长的名字

  • 这是一个32位hash值,目的是防止名字重复
  • 但是,真实开发中,我们可能对打包的图片名字有一定的要求
  • 比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复

我们发现webpack自动帮助我们生成一个非常长的名字

  • 这是一个32位hash值,目的是防止名字重复
  • 但是,真实开发中,我们可能对打包的图片名字有一定的要求
  • 比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复

所以,我们可以在options中添加上如下选项:
在这里插入图片描述

  • img:文件要打包到的文件夹
  • name:获取图片原来的名字,放在该位置
  • hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位
  • ext:使用图片原来的扩展名

在这里插入图片描述
在这里插入图片描述

5.11 ES6语法处理

如果你仔细阅读webpack打包的js文件,发现写的ES6语法并没有转成ES5,那么就意味着可能一些对ES6还不支持的浏览器没有办法很好的运行我们的代码。

  • 在前面我们说过,如果希望将ES6的语法转成ES5,那么就需要使用babel。
  • 而在webpack中,我们直接使用babel对应的loader就可以了。
    在这里插入图片描述
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

在这里插入图片描述

配置webpack.config.js文件:
在这里插入图片描述
重新打包,查看bundle.js文件,发现其中的内容变成了ES5的语法
在这里插入图片描述
完整的package.json:

{"name": "meetwebpack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack"},"author": "","license": "ISC","devDependencies": {"babel-core": "^6.26.3","babel-loader": "^7.1.5","babel-preset-es2015": "^6.24.1","css-loader": "^2.0.2","file-loader": "^3.0.1","less": "^4.1.0","less-loader": "^4.1.0","style-loader": "^0.23.1","url-loader": "^1.1.2","webpack": "^3.6.0"}
}

完整的webpack.config.js文件:

const path = require('path')module.exports = {entry: './src/main.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',publicPath: 'dist/'},module: {rules: [{test: /\.css$/i,// css-loader只负责将css文件进行加载// style-loader负责将样式添加到DOM中// 使用多个loader时,webpack时从右向左读取use: ["style-loader", "css-loader"],},{test: /\.less$/i,use: [{loader: "style-loader"},{loader: "css-loader"},{loader: "less-loader"},]},{test: /\.(png|jpg|gif|jpeg)$/i,use: [{loader: 'url-loader',options: {// 当加载的图片,小于limit时,会将图片编译成base64字符串形式// 当加载的图片,大于limit时,需要使用file-loader模块进行加载limit: 28000,name: 'img/[name].[hash:8].[ext]'},},],},{test: /\.m?js$/,// exclude:排除// include:包含exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['es2015']}}}]}
}

六、webpack中配置Vue

6.1 引入vue.js

后续项目中,我们会使用Vuejs进行开发,而且会以特殊的文件来组织vue的组件。
所以,下面我们来学习一下如何在我们的webpack环境中集成Vuejs

现在,我们希望在项目中使用Vuejs,那么必然需要对其有依赖,所以需要先进行安装
注:因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖
在这里插入图片描述
在这里插入图片描述
那么,接下来就可以按照我们之前学习的方式来使用Vue了
在这里插入图片描述
在这里插入图片描述
修改完成后,重新打包,运行程序:

  • 打包过程没有任何错误(因为只是多打包了一个vue的js文件而已)
  • 但是运行程序,没有出现想要的效果,而且浏览器中有报错

在这里插入图片描述
这个错误说的是我们使用的是runtime-only版本的Vue,什么意思呢?
这里我只说解决方案:Vue不同版本构建,后续我具体讲解runtime-only和runtime-compiler的区别。
在这里插入图片描述
所以我们修改webpack的配置,添加如下内容即可:
在这里插入图片描述
webpack.config.js文件:

const path = require('path')module.exports = {entry: './src/main.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js',publicPath: 'dist/'},module: {rules: [{test: /\.css$/i,// css-loader只负责将css文件进行加载// style-loader负责将样式添加到DOM中// 使用多个loader时,webpack时从右向左读取use: ["style-loader", "css-loader"],},{test: /\.less$/i,use: [{loader: "style-loader"},{loader: "css-loader"},{loader: "less-loader"},]},{test: /\.(png|jpg|gif|jpeg)$/i,use: [{loader: 'url-loader',options: {// 当加载的图片,小于limit时,会将图片编译成base64字符串形式// 当加载的图片,大于limit时,需要使用file-loader模块进行加载limit: 28000,name: 'img/[name].[hash:8].[ext]'},},],},{test: /\.m?js$/,// exclude:排除// include:包含exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['es2015']}}}]},resolve: {// alias:别名alias: {'vue$': 'vue/dist/vue.esm.js'}}
}

在这里插入图片描述
正常运行之后,我们来考虑另外一个问题:

  • 如果我们希望将data中的数据显示在界面中,就必须是修改index.html
  • 如果我们后面自定义了组件,也必须修改index.html来使用组件
  • 但是html模板在之后的开发中,我并不希望手动的来频繁修改,是否可以做到呢?

6.2 el和template区别

定义template属性:

  • 在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容
  • 这里,我们可以将div元素中的{{message}}内容删掉,只保留一个基本的id为div的元素
  • 但是如果我依然希望在其中显示{{message}}的内容,应该怎么处理呢?
    我们可以再定义一个template属性,代码如下:

在这里插入图片描述

重新打包,运行程序,显示一样的结果和HTML代码结构:
在这里插入图片描述
那么,el和template模板的关系是什么呢?

  • 在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
  • 而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。

这样做有什么好处呢?
这样做之后我们就不需要在以后的开发中再次操作index.html,只需要在template中写入对应的标签即可

但是,书写template模块非常麻烦怎么办呢?

  • 没有关系,稍后我们会将template模板中的内容进行抽离。
  • 会分成三部分书写:template、script、style,结构变得非常清晰。

6.3 Vue组件化开发引入

在学习组件化开发的时候,我说过以后的Vue开发过程中,我们都会采用组件化开发的思想。
那么,在当前项目中,如果我也想采用组件化的形式进行开发,应该怎么做呢?

查看下面的代码:
当然,我们也可以将下面的代码抽取到一个js文件中,并且导出。
在这里插入图片描述

6.4 .vue文件封装处理

但是一个组件以一个js对象的形式进行组织和使用的时候是非常不方便的

  • 一方面编写template模块非常的麻烦
  • 另外一方面如果有样式的话,我们写在哪里比较合适呢?

现在,我们以一种全新的方式来组织一个vue的组件

在这里插入图片描述
在这里插入图片描述
但是,这个时候这个文件可以被正确的加载吗?

  • 必然不可以,这种特殊的文件以及特殊的格式,必须有人帮助我们处理。
  • 谁来处理呢?vue-loader以及vue-template-compiler。
    在这里插入图片描述
    参考vue官网进行安装配置
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

安装vue-loader和vue-template-compiler

npm install vue-loader vue-template-compiler --save-dev

在这里插入图片描述
修改webpack.config.js的配置文件:

在这里插入图片描述

执行 npm run build 命令,又出现了报错信息:

在这里插入图片描述
告诉我们要安装一个插件,这是vue-router版本是15以上引起的
需要再额外添加如下配置:
在这里插入图片描述
在这里插入图片描述
执行 npm run build命令,运行成功:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、plugin的使用

7.1 认识plugin

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

loader和plugin区别

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

plugin的使用过程:

  1. 步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
  2. 步骤二:在webpack.config.js中的plugins中配置插件。

下面,我们就来看看可以通过哪些插件对现有的webpack打包过程进行扩容,让我们的webpack变得更加好用。

7.2 BannerPlugin:为打包的文件添加版权声明

我们先来使用一个最简单的插件,为打包的文件添加版权声明
该插件名字叫BannerPlugin,属于webpack自带的插件。

  • 按照下面的方式来修改webpack.config.js的文件:
    在这里插入图片描述
    重新打包程序:查看bundle.js文件的头部,看到如下信息
    在这里插入图片描述

7.3 HtmlWebpackPlugin:打包html的plugin

目前,我们的index.html文件是存放在项目的根目录下的。
我们知道,在真实发布项目时,发布的是dist文件夹中的内容,但是dist文件夹中如果没有index.html文件,那么打包的js等文件也就没有意义了。

所以,我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件

HtmlWebpackPlugin插件可以为我们做这些事情:

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

安装HtmlWebpackPlugin插件

npm install html-webpack-plugin --save-dev

使用插件,修改webpack.config.js文件中plugins部分的内容如下:

在这里插入图片描述
注意:
这里的template表示根据什么模板来生成index.html
另外,我们需要删除之前在output中添加的publicPath属性
否则插入的script标签中的src可能会有问题
在这里插入图片描述
在这里插入图片描述

7.4 uglifyjs-webpack-plugin:js压缩的Plugin

在项目发布之前,我们必然需要对js等文件进行压缩处理 这里,我们就对打包的js文件进行压缩

我们使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致

npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

在这里插入图片描述

修改webpack.config.js文件,使用插件:
在这里插入图片描述

查看打包后的bunlde.js文件,是已经被压缩过了。
在这里插入图片描述

八、搭建本地服务器

webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

不过它是一个单独的模块,在webpack中使用之前需要先安装它

npm install --save-dev webpack-dev-server@2.9.1

在这里插入图片描述

devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

  • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
  • port:端口号
  • inline:页面实时刷新
  • historyApiFallback:在SPA页面中,依赖HTML5的history模式

webpack.config.js文件配置修改如下:
在这里插入图片描述

执行node_modules\.bin\webpack-dev-server命令,启动服务器
在这里插入图片描述

浏览器中输入http://localhost:8080/打开index.html页面:

在这里插入图片描述
或者在package.json文件中配置如下代码:

在这里插入图片描述

执行npm run dev命令,启动本地服务器:
在这里插入图片描述
在这里插入图片描述
我们可以再配置另外一个scripts:
--open参数表示直接打开浏览器
在这里插入图片描述

九、webpack配置的分离

原因:有些配置针对开发环境,有些配置针对生产环境,所以分开配置

  1. 执行命令 npm install webpack-merge --save-dev,安装webpack-merge插件
  2. 建立build文件夹,分别建立 base.config.js prod.config.js dev.config.js
    在这里插入图片描述
  3. 在base.config.js里配置共公部分
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const uglifyJsPlugin = require('uglifyjs-webpack-plugin')
// const {VueLoaderPlugin} = require("vue-loader")
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {entry: './src/main.js',output: {path: path.resolve(__dirname, '../dist'),filename: 'bundle.js',// publicPath: 'dist/'},module: {rules: [{test: /\.css$/i,// css-loader只负责将css文件进行加载// style-loader负责将样式添加到DOM中// 使用多个loader时,webpack时从右向左读取use: ["style-loader", "css-loader"],},{test: /\.less$/i,use: [{loader: "style-loader"},{loader: "css-loader"},{loader: "less-loader"},]},{test: /\.(png|jpg|gif|jpeg)$/i,use: [{loader: 'url-loader',options: {// 当加载的图片,小于limit时,会将图片编译成base64字符串形式// 当加载的图片,大于limit时,需要使用file-loader模块进行加载limit: 28000,name: 'img/[name].[hash:8].[ext]'},},],},{test: /\.m?js$/,// exclude:排除// include:包含exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['es2015']}}},{test: /\.vue$/,loader: 'vue-loader'},]},resolve: {// import导入时,可以省略的后缀名extensions: ['.js','.css','.vue'],// alias:别名alias: {'vue$': 'vue/dist/vue.esm.js'}},plugins: [// 请确保引入这个插件来施展魔法new VueLoaderPlugin(),new webpack.BannerPlugin('最终版权归zep所有'),new HtmlWebpackPlugin({template: 'index.html'}),// new uglifyJsPlugin()],// devServer: {//     contentBase: './dist',//     // 是否实时监听//     inline: true// }
}
  1. 在prod.config.js里配置生产环境
const uglifyJsPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')module.exports = webpackMerge(baseConfig,{plugins: [new uglifyJsPlugin()]}
)
  1. 在dev.config.js里配置开发环境
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')module.exports = webpackMerge(baseConfig,{devServer: {contentBase: './dist',// 是否实时监听inline: true}
})
  1. 在package.json里指定 scripts 里 build 和 dev 所需要找的配置环境路径
    在这里插入图片描述
    package.json文件:
{"name": "meetwebpack","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack --config ./build/prod.config.js","dev": "webpack-dev-server --open --config ./build/dev.config.js"},"author": "","license": "ISC","devDependencies": {"babel-core": "^6.26.3","babel-loader": "^7.1.5","babel-preset-es2015": "^6.24.1","css-loader": "^2.0.2","file-loader": "^3.0.1","html-webpack-plugin": "^3.2.0","less": "^4.1.0","less-loader": "^4.1.0","style-loader": "^0.23.1","uglifyjs-webpack-plugin": "^1.1.1","url-loader": "^1.1.2","vue-loader": "^15.7.0","vue-template-compiler": "^2.5.21","webpack": "^3.6.0","webpack-dev-server": "^2.9.1","webpack-merge": "^4.1.5"},"dependencies": {"vue": "^2.5.21"}
}
  1. 执行npm run build 命令,在浏览器中打开index.html,可以正常显示:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2349. 设计数字容器系统(SortedSet)

文章目录1. 题目2. 解题1. 题目 设计一个数字容器系统,可以实现以下功能: 在系统中给定下标处 插入 或者 替换 一个数字。 返回 系统中 给定数字 的最小下标。 请你实现一个 NumberContainers 类: NumberContainers() 初始化数字容器系统…

七、Vue cli详解学习笔记——什么是Vue cli ,Vue cli的使用(安装,拉取2.x模板,初始化项目),Vue cli2详解,Runtime-Compiler和Runtime-only区别

一、什么是Vue CLI 如果你只是简单写几个Vue的Demo程序, 那么你不需要Vue CLI. 如果你在开发大型项目, 那么你需要, 并且必然需要使用Vue CLI 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。如果每个项目都要手…

我们

我们的 转载于:https://www.cnblogs.com/xxzhou/p/5364606.html

LeetCode 2343. 裁剪数字后查询第 K 小的数字

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的字符串数组 nums ,其中每个字符串 长度相等 且只包含数字。 再给你一个下标从 0 开始的二维整数数组 queries ,其中 queries[i] [ki, trimi] 。对于每个 queries[i] ,你需要&#x…

八、Vue cli3详解学习笔记

一、认识Vue CLI3 1.1 vue-cli 3 与 2 版本有很大区别: vue-cli 3 是基于 webpack 4 打造,vue-cli 2 还是 webapck 3vue-cli 3 的设计原则是“0配置”,移除的配置文件根目录下的,build和config等目录vue-cli 3 提供了 vue ui 命…

LeetCode 1947. 最大兼容性评分和(状态枚举DP)

文章目录1. 题目2. 解题1. 题目 有一份由 n 个问题组成的调查问卷,每个问题的答案要么是 0(no,否),要么是 1(yes,是)。 这份调查问卷被分发给 m 名学生和 m 名导师,学生…

pydev debugger: warning: trying to add breakpoint to file that does not exist: /tmp/xxx

pycharm 在本地,连接远程进行 debug,发现报错 pydev debugger: warning: trying to add breakpoint to file that does not exist: /tmp/EPeOxSnjcK/参考过 https://blog.csdn.net/AAliuxiaolei/article/details/122792931 但是不行。 也试过清除缓存 I…

十、vue-router学习笔记——认识路由、vue-router基本使用、vue-router嵌套路由、vue-router参数传递、vue-router导航守卫、keep-alive

一、认识路由 1.1 什么是路由? 说起路由你想起了什么? 路由是一个网络工程里面的术语。 路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动. — 维基百科 额, 啥玩意? 没听懂 在生活中, 我们有没有听说过路由…

python 基准测试(cProfile \ kcachegrind \ line_profiler \ memory_profiler)

learn from 《Python高性能(第2版)》 类似工具:pycharm profile对函数调用效率进行测试 1. 例子 一个圆周运动的动画 from matplotlib import pyplot as plt from matplotlib import animation from random import uniform import timeit…

纯粹的python优化(数据结构、cache、推导、生成器)

learn from 《Python高性能(第2版)》 1. 数据结构与算法 列表、双端队列 list 底层是数组,在 开头 插入和删除的时间复杂度 O(n), 在结尾插入和删除是 O(1),访问任意元素是 O(1)deque 底层是 双向链表实现&#xff…

解决在vue init webpack my-project卡住的问题(已解决)

执行vue init webpack test命令: 然后cd test,然后cnpm install 或者 npm install --registryhttps://registry.npm.taobao.org 然后执行 npm run dev命令:

十一、案例:TabBar的封装

0、案例效果演示: 一、TabBar实现思路 如果在下方有一个单独的TabBar组件,你如何封装 自定义TabBar组件,在APP中使用 让TabBar出于底部,并且设置相关的样式 TabBar中显示的内容由外界决定 定义插槽 flex布局平分TabBar 自定义Ta…

POJ 3126 Prime Path

水题&#xff1a;直接判断素数bfs 1 #include <iostream>2 #include <cstdio>3 #include <cstring>4 #include <sstream>5 #include <algorithm>6 #include <list>7 #include <map>8 #include <vector>9 #include <queue&g…

十二、Promise的学习笔记(Promise的基本使用、链式编程、all())

一、认识Promise ES6中一个非常重要和好用的特性就是Promise 但是初次接触Promise会一脸懵逼&#xff0c;这TM是什么东西&#xff1f;看看官方或者一些文章对它的介绍和用法&#xff0c;也是一头雾水。 Promise到底是做什么的呢&#xff1f; Promise是异步编程的一种解决方…

十三、Vuex学习笔记

一、Vuex是做什么的? 官方解释&#xff1a;Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。 它采用 集中式存储管理 应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension&#xf…

SQL Server2008附加数据库失败

今天旁晚时分&#xff0c;我准备把老师在上课时候发给我们的一个数据库附加到我的SQL Server2008上面去&#xff0c;本来在学校机房用的SQL Server2000是很顺利地就成功了&#xff0c;但是把*.mdf文件附加到我的08上就不行了&#xff0c;出现了下面的问题&#xff08;图是我 百…

数据解析学习笔记(正则解析、bs4解析、xpath解析)

聚焦爬虫:爬取页面中指定的页面内容。 - 编码流程&#xff1a; - 指定url - 发起请求 - 获取响应数据 - 数据解析 - 持久化存储 数据解析分类&#xff1a; 正则bs4xpath&#xff08;***&#xff09; 数据解析原理概述&#xff1a; - 解析的局部的文本内容都会在标签之间或者标…

Rasa NLU 实践

文章目录1. 目录结构2. nlu.yml3. config.yml4. domain.yml5. 实践learn from https://github.com/Chinese-NLP-book/rasa_chinese_book_code 1. 目录结构 2. nlu.yml version: "3.0" nlu:- intent: greetexamples: |- 你好- hello- hi- 喂- 在么- intent: goodbye…

python3爬虫验证码识别——超级鹰打码平台的使用实战:识别古诗文网登录页面中的验证码

一、验证码和爬虫之间的爱恨情仇&#xff1f; 反爬机制&#xff1a;验证码.识别验证码图片中的数据&#xff0c;用于模拟登陆操作。 二、识别验证码的操作&#xff1a; 人工肉眼识别。&#xff08;不推荐&#xff09;第三方自动识别&#xff08;推荐&#xff09; - 超级鹰打…

python爬虫模拟登录人人网

模拟登录&#xff1a;爬取基于某些用户的用户信息。 需求1&#xff1a;对人人网进行模拟登录。 点击登录按钮之后会发起一个post请求post请求中会携带登录之前录入的相关的登录信息&#xff08;用户名&#xff0c;密码&#xff0c;验证码…&#xff09;验证码&#xff1a;每次…