(十三)、Webpack 打包
1.简介
本质上, webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler)
。当webpack处理应用程序时, 它会递归地构建一个依赖关系图(dependency graph) , 其中包含应用程序需要的每个模块, 然后将所有这些模块打包成一个或多个bundle.
Webpack是当下最热门的前端资源模块化管理和打包工具, 它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源
。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过loader转换, 任何形式的资源都可以当做模块, 比如Commons JS、AMD、ES 6、CSS、JSON、Coffee Script、LESS等;
伴随着移动互联网的大潮, 当今越来越多的网站已经从网页模式进化到了WebApp模式
。它们运行在现代浏览器里, 使用HTML 5、CSS 3、ES 6等新的技术来开发丰富的功能, 网页已经不仅仅是完成浏览器的基本需求; WebApp通常是一个SPA(单页面应用) , 每一个视图通过异步的方式加载,这导致页面初始化和使用过程中会加载越来越多的JS代码,这给前端的开发流程和资源组织带来了巨大挑战。
前端开发和其他开发工作的主要区别,首先是前端基于多语言、多层次的编码和组织工作,其次前端产品的交付是基于浏览器的,这些资源是通过增量加载的方式运行到浏览器端,如何在开发环境组织好这些碎片化的代码和资源,并且保证他们在浏览器端快速、优雅的加载和更新,就需要一个模块化系统,这个理想中的模块化系统是前端工程师多年来一直探索的难题。
2.模块化的演进
<script src = "module1.js"></script> <script src = "module2.js"></script> <script src = "module3.js"></script>
这是最原始的JavaScript文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在window对象中,不同模块的调用都是一个作用域。
弊端:
- 全局作用域下容易造成变量冲突
- 文件只能按照script的书写顺序进行加载
- 开发人员必须主观解决模块和代码库的依赖关系
- 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪
3.CommonsJS
服务器端的NodeJS遵循CommonsJS规范,该规范核心思想是允许模块通过require方法来同步加载所需依赖的其它模块,然后通过exports或module.exports来导出需要暴露的接口。
require("module"); require("../module.js"); export.doStuff = function(){}; module.exports = someValue; 1234
优点:
- 服务器端模块便于重用
- NPM中已经有超过45万个可以使用的模块包
- 简单易用
缺点: - 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
- 不能非阻塞的并行加载多个模块
实现 - 服务端的NodeJS
- Browserify,浏览器端的CommonsJS实现,可以使用NPM的模块,
- 但是编译打包后的文件体积较大
- modules-webmake,类似Browserify,但不如Browserify灵活
- wreq,Browserify的前身
4.AMD
Asynchronous Module Definition规范其实主要一个主要接口define(id?,dependencies?,factory);它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行。
define("module",["dep1","dep2"],functian(d1,d2){ return someExportedValue; }); require(["module","../file.js"],function(module,file){}); 1234
优点
- 适合在浏览器环境中
异步
加载模块 - 可以并行加载多个模块
缺点 - 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不畅
- 不符合通用的模块化思维方式,是一种妥协的实现
实现 - RequireJS
- curl
5.CMD
Commons Module Definition规范和AMD很相似,尽保持简单,并与CommonsJS和NodeJS的Modules规范保持了很大的兼容性。
define(function(require,exports,module){ var $=require("jquery"); var Spinning = require("./spinning"); exports.doSomething = ...; module.exports=...; });
优点
- 依赖就近,延迟执行
- 可以很容易在NodeJS中运行缺点
- 依赖SPM打包,模块的加载逻辑偏重
实现 - Sea.js
- coolie
6.ES6模块
EcmaScript 6标准增加了JavaScript语言层面的模块体系定义。ES 6模块的设计思想, 是尽量静态化, 使编译时就能确定模块的依赖关系
, 以及输入和输出的变量。Commons JS和AMD模块,都只能在运行时确定这些东西。
import "jquery" export function doStuff(){} module "localModule"{}
优点
- 容易进行
静态分析
- 面向未来的Ecma Script标准
缺点 - 原生浏览器端还没有实现该标准
- 全新的命令,新版的Node JS才支持
实现 - Babel
大家期望的模块
系统可以兼容多种模块风格, 尽量可以利用已有的代码, 不仅仅只是JavaScript模块化, 还有CSS、图片、字体等资源也需要模块化。
7.安装Webpack
Webpack 是一款模块加载器打包工具,它把各种资源,如JS,JSX,ES6,SASS,LESS图片等作为模块来处理的作用。
(1).安装
npm install webpack -g npm install webpack-cli -g
(2).配置
创建 webpack.config.js配置文件
- entry:入口文件, 指定Web Pack用哪个文件作为项目的入口
- output:输出, 指定WebPack把处理完成的文件放置到指定路径
- module:模块, 用于处理各种类型的文件
- plugins:插件, 如:热更新、代码重用等
- resolve:设置路径指向
- watch:监听, 用于设置文件改动后直接打包
module.exports = { entry:"", output:{ path:"", filename:"" }, module:{ loaders:[ {test:/\.js$/,;\loade:""} ] }, plugins:{}, resolve:{}, watch:true }
然后直接输入 webpack 就可以打包
8.使用webpack
(1).创建项目
我么先在文件柜中,创建一个文件夹,然后这个文件夹以idea的方式打开。
(2).创建突破口 hello.js
exports.sayHi=function (){ document.write('<h1>你好</h1>') } exports.sayHi1=function (){ document.write('<h1>你好</h1>') } exports.sayHi2=function (){ document.write('<h1>你好</h1>') } exports.sayHi3=function (){ document.write('<h1>你好</h1>') }
(3).创建 接受口 main.js
'use strict' var hello =require('./hello'); hello.sayHi(); hello.sayHi1();
(4).创建 打包配置
module.exports={ entry:'./modules/main.js', output:{ filename:'./js/bundle.js' } };
(5).进行打包 webpack
(6).查看打包文件
(7).引用打包后的工具
(8).效果
(十四)、vue-router 路由
1.vue-router简介
Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成, 让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于Vue js过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的CSS class的链接
- HTML5 历史模式或hash模式, 在IE 9中自动降级
- 自定义的滚动行为
2.安装
基于第一个vue-cli进行测试学习; 先查看node modules中是否存在vue-router
vue-router是一个插件包, 所以我们还是需要用n pm/cn pm来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。
npm install vue-router@3.5.2
3.测试
1、先删除没有用的东西
2、components 目录下存放我们自己编写的组件
3、定义一个Content.vue
的组件在Components目录下
<template> <h1>内容页面</h1> </template> <script> export default { name: "Content" } </script> <style scoped> </style>
4.Src目录下 Main.vue组件
<template> <h1>首页</h1> </template> <script> export default { name: "Main" } </script> <style scoped> </style>
5.安装路由,在src目录下,新建一个文件夹:router,专门存放路由,配置路由index.js
,如下
import Vue from "vue"; import VueRouter from "vue-router"; import Main from "../components/Main"; import Content from "../components/Content"; // 安装路由 Vue.use(VueRouter) //配置到处路由 export default new VueRouter({ routes :[ { // 路由路径 path :'/content', name:'content', // 跳转的组件 component:Content }, { // 路由路径 path :'/main', name:'content', // 跳转的组件 component:Main } ] });