脚手架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 相关文章推荐
jQuery Mobile页面跳转后未加载外部JS原因分析及解决
Mar 18 Javascript
Flex通过JS获取客户端IP和计算机名的实例代码
Nov 21 Javascript
不到30行JS代码实现Excel表格的方法
Nov 15 Javascript
实例讲解js验证表单项是否为空的方法
Jan 09 Javascript
浅谈EasyUi ComBotree树修改 父节点选择的问题
Nov 07 Javascript
Bootstrap 响应式实用工具实例详解
Mar 29 Javascript
微信小程序canvas写字板效果及实例
Jun 15 Javascript
Angular项目中$scope.$apply()方法的使用详解
Jul 26 Javascript
详解JavaScript基础知识(JSON、Function对象、原型、引用类型)
Jan 16 Javascript
小程序云开发获取不到数据库记录的解决方法
May 18 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
Sep 30 Javascript
jQuery实现提交表单时不提交隐藏div中input的方法
Oct 08 jQuery
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
通过文字传递创建的图形按钮
2006/10/09 PHP
php中对2个数组相加的函数
2011/06/24 PHP
php去除html标记的原生函数详解
2015/01/27 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
PHP中quotemeta()函数的用法讲解
2019/04/04 PHP
JS event使用方法详解
2008/04/28 Javascript
jquery 使用点滴函数代码
2011/05/20 Javascript
document.createElement()用法
2013/03/13 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
jQuery prev ~ siblings选择器使用介绍
2013/08/09 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
2014/05/05 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
利用React-router+Webpack快速构建react程序
2016/10/27 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
jQuery设置和获取select、checkbox、radio的选中值方法
2017/01/01 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
全面介绍vue 全家桶和项目实例
2017/12/27 Javascript
详解.vue文件中style标签的几个标识符
2018/07/17 Javascript
对angular 监控数据模型变化的事件方法$watch详解
2018/10/09 Javascript
java实现单链表增删改查的实例代码详解
2019/08/30 Javascript
微信小程序拼接图片链接无底洞深入探究
2019/09/03 Javascript
Layui 数据表格批量删除和多条件搜索的实例
2019/09/04 Javascript
python让图片按照exif信息里的创建时间进行排序的方法
2015/03/16 Python
python交互式图形编程实例(二)
2017/11/17 Python
Python即时网络爬虫项目启动说明详解
2018/02/23 Python
python Elasticsearch索引建立和数据的上传详解
2019/08/04 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
Django关于admin的使用技巧和知识点
2020/02/10 Python
Python中实现输入一个整数的案例
2020/05/03 Python
Ashford台湾:以折扣价提供奢华的男女用表款
2019/12/04 全球购物
工商管理专业大学生职业生涯规划范文
2014/03/09 职场文书
销售经理岗位职责
2014/03/16 职场文书
党的群众路线教育实践方案
2014/05/11 职场文书
八一建军节主持词
2015/07/01 职场文书
原生JavaScript实现简单五子棋游戏
2021/06/28 Javascript
golang 语言中错误处理机制
2021/08/30 Golang