脚手架vue-cli工程webpack的基本用法详解


Posted in Javascript onSeptember 29, 2018

webpack的打包依赖于它的一个重要配置文件webpack.config.js,在这个配置文件中就可以指定所有在源代码编译过程中的工作了,就一个配置就可以与冗长的Gruntfile或者Gulpfile说再见了。

一个完整的工程项目中的webpack的配置远远没有这么简单,随着工程的构建要求的增加,webpack.config.js内的配置项目也会随之增加,webpack还有许许多多的选项提供给我们进行灵活配置,它只是一个构建工具,我们只需要了解在Vue项目中它基本能为我们做到的工作、最小化的配置是如何的就足够了,在以后需要对它进行扩展与优化时,带着问题去查官方文档也是非常容易的事。

●  样式表引用

某些页面或者组件可能具有特定的样式定义,这些样式对于其他页面来说是冗余的,我们只希望这些组件在应用时才自动加载这些特定的样式,此时用webpack我们就能在源代码中加入以下代码来动态加载CSS:

import Vue from 'vue'
// ... 省略
// 引用指定的样式源文件
import './app/assets/less/dark.less'
export default {
 // ... 省略
}

此时我们只需要在webpack的配置中加入less-loader,那么webpack在打包的时候就会自动将less转换为CSS,并将CSS的动态代码生成到JS文件中。当Vue组件被加载到页面并实例化后,将在DOM内插入这个特定的行内样式<style>以实现动态样式的应用。

对于*.css文件同样也是适用的,例如导入某个第三方库中必需的样式表:

import 'uikit/dist/css/components/tabs.css'

●  字体的引用

假设在dark.less内加入对自定义字体文件的样式定义:

@font-face {
  font-family: 'Darkenstone';
  src: url('./Darkenstone.eot');
  src: url('./Darkenstone.eot?#iefix') format('embedded-opentype'),
   url('./Darkenstone.woff2') format('woff2'),
   url('./Darkenstone.woff') format('woff'),
   url('./Darkenstone.ttf') format('truetype'),
   url('./Darkenstone.svg#Darkenstone') format('svg');
   font-weight: normal;   
   font-style: normal;
}
.header{
  display: flex;
  flex-flow: row nowrap;
  & > h1 {
   font: 16pt 'Darkenstone';
  }
}

这里.header>h1指定了一个Darkenstone的自定义字体,这个字体浏览器一定是不能识别的,以前我们在样式表中先定义这个字体样式并指定加载位置(如上文@font-face的定义),然后在页面中引用这个样式表,这是多么麻烦的一件事,不是吗?

如果用了webpack后,我们只是在配置文件内加入了一个url-loader:

{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url'
}

我们并不需要在源代码中做任何改变,因为之前已经引用过样式表dark.less,而字体是在样式表中的,webpack将在打包的时候为我们识别并在代码中引入字体的动态加载。这样一来极大地解决了我们对资源引用的依赖问题!

vue-cli的webpack模板已经为我们配置好了绝大多数常用的loader,在实际运用中我们只需要了解它们是怎么来的,应该怎么用,需要的时候如何修改就够了。

●  用别名取代路径引用

在项目开发过程中有可能有许多包是没有放在npm上的,有一些较老的可能还依然只存在于bower上,某些甚至在bower与npm上都找不到,而不得不通过下载的方式在项目内引用,这样一来我们的代码可能通过require就得在代码内引用一段很长的文件路径,如下所示

{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url'
}

这种包的引用方式明显违反了CommonJS的编程规范,对于这些长路径,甚至还具有“../..”这些相对路径搜索的定义,我们可以通过webpack的resolve配置项来解决。就以select这个组件为例,在webpack.base.config.js中加入以下的这个别名的定义:

module.exports = {
 entry:{ ... },
 output: { ... },
 module:{ ... },
 resolve: {
  extensions:['','.js'],
  alias:{ // 别名
   'bs-select':'bower_components/bootstrap-select/dist/js/select.js'
  }
 }
}

有了这个定义以后,我们就可以将上面那个长引用改为下面的写法:

import Selector from 'bs-select';

绝对不要让路径引用进入到我们的代码,因为这是代码的“癌症”,一旦开始植入并生长起来,以前的代码将难以维护!

●  配置多入口程序

多数情况下我们的程序入口不单单只有一个,举一个最简单的例子,前台提供给最终用户使用(http://www.domain.com/index),后台提供给登录用户使用(http://www.domain.com/admin/),那么自然需要多个与main.js类似的程序入口了。

首先在build/webpack.base.conf.js配置文件中的entry配置属性上加上新的入口文件:

module.exports = {
 entry: {
 app: './src/main.js',
 admin : './src/admin-main.js'
 },
 // ... 省略
}

这是用于告诉webpack哪几个是入口文件,这些文件需要被生成到启动页的<script>内。

vue-cli的webpack模板使用HtmlWebpackPlugin插件,生成HTML入口页面并自动将生成后的JS文件和CSS文件的引用地址写入到页内的<script>中。

这里就需要在build/webpack.dev.config.js文件内的plugins配置项内多配置一个HtmlWebpackPlugin插件,用于生成admin.html入口页。

plugins:[
 // ... 省略
 // 这是原有的配置项,用于匹配注入app.js的输出脚本
 new HtmlWebpackPlugin({
 filename: process.env.NODE_ENV === 'testing'
  ? 'index.html'
  : config.build.index,
 template: 'index.html',
 chunks: ['app'], // 与原配置的不同的是要用chunks指定对应的entry
 inject: true,
 minify: {
  removeComments: true,
  collapseWhitespace: true,
  removeAttributeQuotes: true
 },
 chunksSortMode: 'dependency'
 }),
 // 这是新增项,用于匹配注入admin.js的输出脚本
 new HtmlWebpackPlugin({
 filename: process.env.NODE_ENV === 'testing'
  ? 'admin.html'
  : config.build.admin,
 template: 'index.html',
 chunks: ['admin'],
 inject: true,
 minify: {
  removeComments: true,
  collapseWhitespace: true,
  removeAttributeQuotes: true
 },
 chunksSortMode: 'dependency'
 }),
]

需要强调一点的是,这里的HtmlWebpackPlugin配置必须用chunks指定在上文entry内对应的入口文件的别名。

关于HtmlWebpackPlugin更多配置内容可以参考:https://github.com/kangax/html-minifier#options-quick-reference。

还有就是得将同样的配置加入到生产环境专用的webpack配置文件webpack.prod.conf.js中,否则当我们运行npm run build时是不会输出admin.js和admin.html这两个入口文件的(由于配置内容相同这里就不再重复了)。

最后,如果使用了vue-router就得对connect-history-api-fallback插件的配置进行修改,否则原有的默认配置只会将所有的请求转发给index.html,这样就会导致History API没有办法正确地将请求指向admin.html,导致热加载失败,具体做法如下所述。

打开dev-server.js文件,将app.use(require('connect-history-api-fallback')())配置改为以下的方式:

// handle fallback for HTML5 history API
var history = require('connect-history-api-fallback')
// app.use(require('connect-history-api-fallback')())
app.use(history({
 rewrites: [
 { from: /^\/admin\/.*$/, to: '/admin.html' }
 ]
}));

新入口需要有明确区分的路由规则,否则还是会产生热加载失败的情况,这样就非常不便于开发了。

总结

以上所述是小编给大家介绍的脚手架vue-cli工程webpack的基本用法详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 监听textarea中按键事件
Oct 08 Javascript
使用javascipt---实现二分查找法
Apr 10 Javascript
文本框(input)获取焦点(onfocus)时样式改变的示例代码
Jan 10 Javascript
jQuery控制Div拖拽效果完整实例分析
Apr 15 Javascript
javascript实现连续赋值
Aug 10 Javascript
JQuery fileupload插件实现文件上传功能
Mar 18 Javascript
单击按钮发送验证码,出现倒计时的简单实例
Mar 17 Javascript
JS实现向iframe中表单传值的方法
Mar 24 Javascript
通过构造函数实例化对象的方法
Jun 28 Javascript
详解vue axios二次封装
Jul 22 Javascript
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
May 27 Javascript
vue中选中多个选项并且改变选中的样式的实例代码
Sep 16 Javascript
vue实现条件判断动态绑定样式的方法
Sep 29 #Javascript
vue根据值给予不同class的实例
Sep 29 #Javascript
vue实现重置表单信息为空的方法
Sep 29 #Javascript
Vue中的Props(不可变状态)
Sep 29 #Javascript
vue动态删除从数据库倒入列表的某一条方法
Sep 29 #Javascript
使用vue根据状态添加列表数据和删除列表数据的实例
Sep 29 #Javascript
vue-cli脚手架搭建的项目去除eslint验证的方法
Sep 29 #Javascript
You might like
PHP文件去掉PHP注释空格的函数分析(PHP代码压缩)
2013/07/02 PHP
YII使用url组件美化管理的方法
2015/12/28 PHP
php闭包中使用use声明变量的作用域实例分析
2018/08/09 PHP
非常强大的 jQuery.AsyncBox 弹出对话框插件
2011/08/29 Javascript
《JavaScript高级程序设计》阅读笔记(一) ECMAScript基础
2012/02/27 Javascript
IE中jquery.form中ajax提交没反应解决方法分享
2012/09/11 Javascript
node.js正则表达式获取网页中所有链接的代码实例
2014/06/03 Javascript
提高jQuery性能优化的技巧
2015/08/03 Javascript
BootStrap网页中代码显示用法详解
2016/10/21 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
2016/11/11 Javascript
JS正则表达式常见用法实例详解
2018/06/19 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
2018/08/01 Javascript
JS 实现获取验证码 倒计时功能
2018/10/29 Javascript
jQuery实现上下滚动公告栏详细代码
2018/11/21 jQuery
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
JavaScript 作用域实例分析
2019/10/02 Javascript
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
Python排序搜索基本算法之插入排序实例分析
2017/12/11 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
Django Web开发中django-debug-toolbar的配置以及使用
2018/05/06 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
2018/12/28 Python
python 进程的几种创建方式详解
2019/08/29 Python
Pytorch: 自定义网络层实例
2020/01/07 Python
python代码xml转txt实例
2020/03/10 Python
python 将html转换为pdf的几种方法
2020/12/29 Python
大女孩胸罩:Big Girls Bras
2016/12/15 全球购物
XMLHttpRequest对象在IE和Firefox中创建方式有没有不同
2016/03/23 面试题
三分钟演讲稿事例
2014/03/03 职场文书
开学典礼主持词
2014/03/19 职场文书
绿色家庭事迹材料
2014/05/01 职场文书
综合素质自我评价评语
2015/03/06 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
公司人事管理制度
2015/08/05 职场文书
Python快速实现一键抠图功能的全过程
2021/06/29 Python
Java实现房屋出租系统详解
2021/10/05 Java/Android