详解如何使用webpack打包Vue工程


Posted in Javascript onMay 27, 2017

使用webpack打包Vue工程

前言

入行一年,从什么都不懂的小白,到现在什么都懂一点的小白,也算是飞跃了。感叹一下现在的前端,从nodejs出来到现在各种各样的工具如雨后春笋般的出现。大神们疯狂的造轮子,玩的不亦乐乎。我等小白们,疯狂追赶,学的心肝脾肺都快衰竭。而我的精力也仅限浅尝辄止,但是学多一点总有好处的。本篇文章就是介绍如何使用webpack构建前端工程。

目标

本次的工程以Vue.js为主角,Vue.js是一款小巧优雅而且强大的轻量级mvvm框架,配合webpack模块化打包。制作出如下图的效果。仅仅搭一个框架,会用上很多插件和加载器。

详解如何使用webpack打包Vue工程

环境准备

主要是一些全局的nodejs包

  1. Nodejs
  2. npm
  3. webpack
  4. less
sudo npm install webpack -g // -g 代表全局安装webpack,调出命令行即可使用webpack命令
sudo npm install less -g   // -g 全局安装 less to css 转换器

开始

1. 初始化工程

创建工程文件夹 new 并定位到 new

mkdir new && cd new

使用npm初始化工程

npm init

根据需要设置项目的信息, 也可以一路回车,使用默认信息,默认项目名称为文件夹名(项目名称不要设置成某个模块名,否则将来你引用摸个模块的时候会报错)

name: (new) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: new
author: fz
license: (ISC) 


{
 "name": "gt",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
  "new"
 ],
 "author": "fz",
 "license": "ISC"
}

Is this ok? (yes)

之后文件夹下会生成一个package.json,记录了项目的详细信息,包括了各种依赖和插件。

2. 创建目录以及webpack配置文件

├── dist      // 编译之后输出文件的目录
├── src       // 应用逻辑代码存放区域
│  ├── lib    // 存放npm上找不到的第三方库
│  │  ├── backbone.js
│  │  └── underscore.js
│  ├── static   // 存放静态资源
│  │  └── logo.png
│  ├── app.html  // 部件模板
│  ├── app.js   // 部件代码
│  └── app.less  // 部件样式
├── index.html   // 应用首页模板
├── index.js    // 应用入口
├── package.json  // 工程配置文件
└── webpack.config.js // webpack配置文件

现在的目录结构,文件都是空白的,等一下把他们补上。

3. 安装webpack各中模块的loader(加载器)和插件以及我们需要的模块

npm install --save less     // 本地按装less
npm install --save less-loader  // less模块的加载器,配合下面css-loader 和 style-loader
npm install --save css-loader  // css 模块加载器
npm install --save style-loader // 以上两个插件的根基
npm install --save url-loader  // 用来处理 图片 字体 的模块,是由下面file-loader封装的。可自定义文件名
npm install --save file-loader 
npm install --save html-loader  // 加载html文件用的
npm install --save text-loader  // 加载纯文本用的
npm install --save html-webpack-plugin      // 生成html文件插件
npm install --save extract-text-webpack-plugin  // 单独提取css文件插件
npm install --save webpack            // 提供webpack对象
npm install --save webpack-dev-server      // webpack-server开发包,方便调试
npm install --save vue
npm install --save jquery

4. 完成后的package.json

{
 "name": "new",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
  "dev": "webpack-dev-server --hot --inline",  // 用户启动 webpack-dev-server 用于用户调试 --hot 代表热替换 , --inline 模式。。不太清楚。
  "test": "echo \"Error: no test specified\" && exit 1"
 },
 "keywords": [
  "new"
 ],
 "author": "fz",
 "license": "ISC",
 "dependencies": {
  "bootstrap": "^3.3.6",
  "css-loader": "^0.23.1",
  "extract-text-webpack-plugin": "^1.0.1",
  "file-loader": "^0.9.0",
  "html-loader": "^0.4.3",
  "html-webpack-plugin": "^2.22.0",
  "jquery": "^2.1.4",
  "less": "^2.7.1",
  "less-loader": "^2.2.3",
  "style-loader": "^0.13.1",
  "text-loader": "0.0.1",
  "url-loader": "^0.5.7",
  "vue": "^1.0.26",
  "webpack": "^1.13.1",
  "webpack-dev-server": "^1.14.1"
 }
}

3. 编写webpack.config.js配置文件

webpack配置文件比较复杂,需要做一下说明:webpack作为一款模块打包器,其管理的单元就是模块,webpack的模块指的不仅仅是js,包括了样式,图片,字体,模板等等。不同的模块需要相应的loader作为加载器进行加载。

var webpack = require('webpack');
var path = require('path');
var htmlWebpackPlugin = require('html-webpack-plugin');
var extractTextWebpackPlugin = require('extract-text-webpack-plugin');

引入必要的插件和模块

module.exports = {
  entry: {
    "index": "./index.js",
    "common": ['vue', 'jquery', 'underscore', 'backbone']
  },

entry 顾名思义就是入口,他是程序的入口,但它同时也是chunk(代码块)构造器。构造有两种方式,上面一种,通过文件内require的模块关系,将文件打包成chunk。下面一种意思就是组成这个chunk的是这几个模块(backbone,underscore等三方模块的定义在下面, vue,jQuery,可以直接通过npm安装)。

这个配置会编译出两个文件,一个当作公共库使用,一个当作网站入口使用。

output: {
    path: './dist',    
    publicPath: '/path/',   
    filename: '[name].[hash].js'  
  },

很明显,这里是输出文件控制

  1. path: 输出编译后文件路径
  2. publicPath: 在html-webpack-plugin中,中引入脚本的根目录。(生成)
  3. filename: 输出文件名,[name]的意思就是原来chunk代码块叫什么名字就是什么名字,[hash],文件的哈希值。

例如: 入口文件名叫index,那么它的输出就是index.d87f87sd6fsdgs76gsd967.js

module: {
    loaders: [
      {
        test: /\.less$/,
        loader: 'style-loader!css-loader!less-loader'
      },
      {
        test: /\.less$/,
        loader: extractTextWebpackPlugin.extract("style-loader", "css-loader!less-loader")
        // 配合‘extract-text-webpack-plugin'可以剥离,css
      },
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader'
      },
      {
        test: /\.(png|jpg|gif|woff|woff2|ttf|eot|svg)$/,
        loader: 'url-loader?limite=8192'  // limit 是转换base64的文件大小的阀值8兆
      },
      {
        test: /\.html$/,
        loader: 'html-loader'  // 可以用来加载模板
      }
    ]
  },

module 这部分,我不是很了解,只知道这里可以用于loader定义。loaders是一个数组。

  1. test: 定义加载模块的文件名正则表达式
  2. loader: 定义加载模块的加载器

加载器可以多个配合使用,典型的就是style css less,逻辑还是很清晰的,less 转 css 转 样式模块,然后插入文档。

resolve: {
    root: [
      path.resolve(__dirname, 'src/lib')
    ],
    extensions: ['', '.js'],
    alias: {
      'underscore': 'underscore.js',
      'backbone': 'backbone.js',
    }
  },

解析模块功能,用来解析三方模块和一些require不方便的模块。

  1. root: 模块搜索路径数组,告诉webpack从哪里去找模块。我这里定义了一个src/lib路径,我把一些库放在这个路径下面。引用的时候,可以直接require(‘underscore.x.x.x.js');不必加路径。
  2. extensions: 拓展名,设置扩展名后,可以require(‘underscore'),不必加.js,这里一定要设置,否则,webpack-dev-server 会报错,真心坑爹。
  3. alias: 经过上面的设置,已经可以随心所欲引入三方模块了,但是我觉得使用别名的方式更好,更方便管理。在文件中引用公共库的时候避免使用路径的方式,例如require(‘../../lib/ssssss.js')。在别名中定义好即可。
plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common',
      filename: '[name].[hash].js',
      chunks: ['index', 'common']  // extract commonChunk from index & common
    }),
    new htmlWebpackPlugin({
      template: './index.html',
      filename: 'index.html',
      chunks: ['index', 'common']
    }),
    new webpack.ProvidePlugin({
      jQuery: "jquery"
    }),
    new webpack.optimize.UglifyJsPlugin(),
    new extractTextWebpackPlugin("style.css", {
      allChunks: true
    })
  ]
};

插件库定义

  1. CommonsChunkPlugin 这个插件就是用于提取公共模块的插件,它从chunks中的若干个chunk代码块中分析出他们公用的模块,并打包成name定义的chunk代码块,你会发现common代码块和入口的common代码块重名,我们可以重新写一个新的名字。也可以不写。假如重名,生成的common.js中包好的模块是entry入口定义的所有模块。[‘vue', ‘jquery', ‘underscore', ‘backbone'],这样也比较好理解,因为我们。
  2. htmlWebpackplugin 插件不是webpack自带的插件,它的作用是根据chunk代码块生成文档,下面的意思就是在index.html中引入index.js代码和common.js代码。
  3. webpack.ProvidePlugin 插件用于有些库,比如bootstrap,打包不会出错,但是放在浏览器下就出问题,原因是bootstrap在初始化的时候要传入全局的jQuery变量,webpack中各模块都是独立的,jquery也是,jQuery无法赋值到window上,导致报错,这时候,这个插件就派上用场了,将jquery模块输出到全局的jQuery变量上。bootstrap不再报错
  4. extractTextWebpackPlugin 这个外部插件可以将css文件独立剥离出来,保存为一个单独的样式文件。

插件可以更具开发环境定义,因为插件越多,编译越慢,我们在开发环境的时候其实不需要那么多插件,生产环境的时候才需要,所以可以做一些处理,动态添加插件。这里有文章可以做,不介绍。

4. 写逻辑代码

// index.js

var Vue = require('vue');

var app = new Vue({
  el: '#app',
  components: {
    app: require('./src/app.js')
  }
});

require('vue'),使用vue模块,新建vue实例,(vue的具体用法上官网),内建一个app字组件,用同步的方法获取在./src/目录下的app.js模块。

// index.html 入口模板

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>vueapp</title>
</head>
<body id="app">
  <app></app>
</body>
</html>

html-webpack-plugin会自动生成插入的script,制成入口。

// app.js

var template = require('./app.html');
require('./app.less');

module.exports = {
  template: template,
  data: function (){
    return {
      message: 'hello word!!'
    };
  }
};
// app.html 视图模板

<div id="div1">
  <img src="./static/logo.png" alt="">
  <div id="div2">
    {{message}}
  </div>
</div>
// app.less 视图样式

#div1 {
  text-align: center;
}

#div2 {
  font-size: 30px;
}

定义一个视图,作为首页,引入模板,引入样式,一个SPA的架子就这么搭好了。

5. 编译

在工程目录下命令行输入

webpack

生成目录

├── dist
│  ├── common.6b92c6b075a69a71d22f.js
│  ├── index.6b92c6b075a69a71d22f.js
│  ├── index.html
│  └── style.6b92c6b075a69a71d22f.css

编译完成,可以看到以上的目录,common为公共提取的模块,style是公共提取的css文件,index.js,逻辑入口。项目打包完成。

6. 调试开发

webpack 提供了 weppack-dev-server 插件,很方便我们进行调试,我们在package.json的script中定义一个命令:

'dev': 'webpack-dev-server --hot --inline'

我们就可以在命令行中输入 npm run dev,在浏览器输入localhost:8080就可以看到网页了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
node.js中的fs.writeFile方法使用说明
Dec 14 Javascript
JavaScript计算两个日期时间段内日期的方法
Mar 16 Javascript
JavaScript使用二分查找算法在数组中查找数据的方法
Apr 07 Javascript
jQuery实现页面内锚点平滑跳转特效的方法总结
May 11 Javascript
初识Javascript小结
Jul 16 Javascript
理解javascript正则表达式
Mar 08 Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 Javascript
Angular 4.0学习教程之架构详解
Sep 12 Javascript
Vue官网todoMVC示例代码
Jan 29 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
Jul 09 Javascript
angular4自定义表单控件[(ngModel)]的实现
Nov 23 Javascript
Javascript读写cookie的实例源码
Mar 16 Javascript
Jquery中attr与prop的区别详解
May 27 #jQuery
angular使用post、get向后台传参的问题实例
May 27 #Javascript
AngularJS中使用ngModal模态框实例
May 27 #Javascript
angularJS模态框$modal实例代码
May 27 #Javascript
AngularJS入门教程二:在路由中传递参数的方法分析
May 27 #Javascript
AngularJS入门教程一:路由用法初探
May 27 #Javascript
Angular 4环境准备与Angular cli创建项目详解
May 27 #Javascript
You might like
深入php define()函数以及defined()函数的用法详解
2013/06/05 PHP
php中函数前加&amp;符号的作用分解
2014/07/08 PHP
destoon实现资讯信息前面调用它所属分类的方法
2014/07/15 PHP
laravel 4安装及入门图文教程
2014/10/29 PHP
PHP中功能强大却很少使用的函数实例小结
2016/11/10 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
2016/12/27 PHP
PHP chr()函数讲解
2019/02/11 PHP
超强的IE背景图片闪烁(抖动)的解决办法
2007/09/09 Javascript
JS动态添加option和删除option(附实例代码)
2013/04/01 Javascript
JavaScript根据数据生成百分比图和柱状图的实例代码
2013/07/14 Javascript
常见的原始JS选择器使用方法总结
2014/04/09 Javascript
javascript数组去重方法终极总结
2014/06/05 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
2015/03/25 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
2016/06/03 Javascript
Vue表单实例代码
2016/09/05 Javascript
Sequelize中用group by进行分组聚合查询
2016/12/12 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
vue的全局变量和全局拦截请求器的示例代码
2018/09/13 Javascript
[00:12]DAC SOLO赛卫冕冠军 VG.Paparazi灬展现SOLO技巧
2018/04/06 DOTA
基于Python实现的扫雷游戏实例代码
2014/08/01 Python
Python中使用ConfigParser解析ini配置文件实例
2014/08/30 Python
Python实现视频下载功能
2017/03/14 Python
Python爬豆瓣电影实例
2018/02/23 Python
Django rest framework实现分页的示例
2018/05/24 Python
python使用PIL实现多张图片垂直合并
2019/01/15 Python
Python实用工具FuckIt.py介绍
2019/07/02 Python
简单了解python gevent 协程使用及作用
2019/07/22 Python
JupyterNotebook 输出窗口的显示效果调整方法
2020/04/13 Python
Python如何将模块打包并发布
2020/08/30 Python
Pycharm学生免费专业版安装教程的方法步骤
2020/09/24 Python
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
2013/01/09 HTML / CSS
新西兰床上用品和家居用品购物网站:Adairs
2018/04/27 全球购物
中专生自我鉴定范文
2013/12/19 职场文书
车间安全生产标语
2014/06/06 职场文书
运动会方阵口号
2014/06/07 职场文书
大学同学会活动方案
2014/08/20 职场文书