vue----webpack

Webpack 简介

概述

  本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

  Webpack 是当下最热门的前端资源模块化管理和打包工具,它可以将许多松散耦合的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分离,等到实际需要时再异步加载。通过 loader 转换,任何形式的资源都可以当做模块,比如 CommonsJS、AMD、ES6、CSS、JSON、CoffeeScript、LESS 等;

  WebPack 是一款模块加载器兼打包工具,它能把各种资源,如 JS、JSX、ES6、SASS、LESS、图片等都作为模块来处理和使用。

  Webpack是一个前端资源的打包工具,它可以将is、image、sss等资源当成一个模块进行打包(下图展示了所有的js打包成一个js,css打包成一个css等)

  好处:

  • 1、模块化开发
程序员在开发时可以分模块创建不同的js、 css等小文件方便开发,最后使用webpack将这些小文件打包成一个文件,减少了http的请求次数。webpack可以实现按需打包,为了避免出现打包文件过大可以打包成多个文件。
  • 2、 编译typescript、ES6等高级js语法
随着前端技术的强大,开发中可以使用javascript的很多高级版本,比如:typescript、ES6等,方便开发,webpack可以将打包文件转换成浏览器可识别的js语法。
  • 3、CSS预编译
webpack允许在开发中使用Sass 和 Less等原生CSS的扩展技术,通过sass-loader、less-loader将Sass 和 Less的语法编译成浏览器可识别的css语法。 

  

模块化的演进

Script 标签

<script src="module1.js"></scirpt>
<script src="module2.js"></scirpt>
<script src="module3.js"></scirpt>
<script src="module4.js"></scirpt>

  

这是最原始的 JavaScript 文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window 对象中,不同模块的调用都是一个作用域。

这种原始的加载方式暴露了一些显而易见的弊端:

  • 全局作用域下容易造成变量冲突
  • 文件只能按照 <script> 的书写顺序进行加载
  • 开发人员必须主观解决模块和代码库的依赖关系
  • 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪

CommonsJS

  服务器端的 NodeJS 遵循 CommonsJS 规范,该规范核心思想是允许模块通过 require 方法来同步加载所需依赖的其它模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

require("module");
var test = require("../module.js");
test.test();


export.doStuff = function() {};
module.exports = someValue;

优点

  • 服务器端模块便于重用
  • NPM 中已经有超过 45 万个可以使用的模块包
  • 简单易用

缺点

  • 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的
  • 不能非阻塞的并行加载多个模块

实现

  • 服务端的 NodeJS
  • Browserify,浏览器端的 CommonsJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积较大
  • modules-webmake,类似 Browserify,但不如 Browserify 灵活
  • wreq,Browserify 的前身

AMD

  Asynchronous Module Definition 规范其实主要一个主要接口 define(id?, dependencies?, factory); 它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行。

  Asynchronous Module Definition 规范其实主要一个主要接口 define(id?, dependencies?, factory); 它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行。

define("module", ["dep1", "dep2"], function(d1, d2) {
  return someExportedValue;
});
require(["module", "../file.js"], function(module, file) {});

优点

  • 适合在浏览器环境中异步加载模块
  • 可以并行加载多个模块

缺点

  • 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不畅
  • 不符合通用的模块化思维方式,是一种妥协的实现

实现

  • RequireJS
  • curl

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

ES6 模块

  EcmaScript6 标准增加了 JavaScript 语言层面的模块体系定义。 ES6 模块的设计思想,是尽量静态化,使编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonsJS 和 AMD 模块,都只能在运行时确定这些东西。

import "jquery";
export function doStuff() {}
module "localModule" {} 

优点

  • 容易进行静态分析
  • 面向未来的 EcmaScript 标准

缺点

  • 原生浏览器端还没有实现该标准
  • 全新的命令,新版的 NodeJS 才支持

实现

  • Babel

期望的模块系统

  可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅只是 JavaScript 模块化,还有 CSS、图片、字体等资源也需要模块化。

  用webpack实现

 

安装webpack

安装Node.js

  webpack基于node.js运行,首先需要安装node.js。

node.js概述

  Node.js是一个Javascript运行环境(runtime environment),发布于2009年5月,由Ryan Dah开发,实质是对Chrome V8引擎进行了封装。Node js对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好。
  V8引擎执行Javascript的速度非常快,性能非常好。Nodejs是一个基于Chrome JavaScript运行时建立的平台,用于方便地搭建响应速度快、易于扩展的网络应用。Nodejs使用事件驱动,非阻塞/O模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。

  传统意义上的JavaScript运行在浏览器上,Chrome使用的JavaScript引擎是V8,Node.js是一个运行在服务端的框架,它的底层就使用了V8引擎,这样就可以使用javascript去编写一些服务端的程序,这样也就实现了用javaScript去开发Apache+PHP以及Java Servlet所开发的服务端功能,这样做的好处就是前端和后端都采用javascript,即开发一份js程序即可以运行在前端也可以运行的服务端,这样比一个应用使用多种语言在开发效率上要高,不过node.js属于新兴产品,一些公司也在尝试使用node.js完成一些业务领域,node.js基于V8引擎,基于事件驱动机制,在特定领域性能出色,比如用node.js实现消息推送、状态监控等的业务功能非常合适。
  对于我们平常开发,前端使用的是js,后端使用的是java,python开发的服务器;
  对于node.js,前端使用js,后端使用node.js作为服务器

安装node.js

  下载地址:https://nodejs.org/en/download/,推荐下载LTS版本
  添加环境变量,测试 node -v

安装NPM

  node.js需要使用npm来安装node.js需要的依赖包,就像python中的pip一样
  npm全称Node Package Manager,他是node包管理和分发的工具,使用NPM可以对应用的依赖进行管理,NPM的功能和服务端项目构建工具maven差不多,npm的工作原理:去远程下载所依赖的js包。
  node.js已经集成了npm工具,在命令提示符输入 npm -v 可查看当前npm版本。
 
  使用 npm config ls 查询NPM管理包路径(NPM下载的依赖包所存放的路径,默认路径C:/用户/[用户名]/AppData/Roming/npm/node_meodules)
  修改路径(首先创建目录):修改完了查看配置是否生效 npm config ls
npm config set prefix "D:
odejs
pm_modules"
npm config set cache "D:
odejs
pm_cache"

  将D: odejs pm_modules添加到环境变量中

安装cnpm

  npm默认会去国外的镜像去下载js包,在开发中通常我们使用国内镜像,这里我们使用淘宝镜像
  下边我们来安装cnpm:有时我们使用npm下载资源会很慢,所以我们可以安装一个cnmp(淘宝镜像)来加快下载速度。
  输入命令,进行全局安装淘宝镜像。(--registry:注册淘宝镜像)
npm install -g  cnpm --registry=https://registry.npm.taobao.org

  查看cnpm版本

cnpm -v

安装nrm

  切换cnpm镜像地址(执行下面命令需要去下载好的nrm目录,如果没有添加环境变量)

cnpm install -g nrm  //安装
nrm ls               //查询当前指向的镜像地址
nrm use taobao       //切换到淘宝镜像

安装webpack

  • 本地安装
  仅将webpack安装在当前项目的node_modules目录中,仅对当前项目有效。(不单单是webpack可以在本地安装)
  在门户目录下创建webpack测试目录webpacktest01
  npm install --save-dev webpack 或 cnpm install --save-dev webpack
  npm install --save-dev webpack-cli (4.0以后的版本需要安装webpack-cli)
  • 全局安装加-g,如下:
  全局安装就将webpack的js包下载到npm的包路径下。
  npm install webpack -g 或 cnpm install webpack -g
npm install webpack -g
npm install webpack-cli -g

webpack入门程序

配置

创建 webpack.config.js 配置文件

  • entry:入口文件,指定 WebPack 用哪个文件作为项目的入口
  • output:输出,指定 WebPack 把处理完成的文件放置到指定路径
  • module:模块,用于处理各种类型的文件
  • plugins:插件,如:热更新、代码重用等
  • resolve:设置路径指向
  • watch:监听,用于设置文件改动后直接打包
module.exports = {
    entry: "", //指定入口文件(main.js)
    output: {
        path: "", //需要是绝对路径,默认是./dist/filename.js
        filename: ""
    },
    module: {
        loaders: [
            {test: /.js$/, loader: ""}
        ]
    },
    plugins: {},
    resolve: {},
    watch: true
}  

执行

  直接运行 webpack 命令打包

使用 WebPack

示例

  • 创建项目
  • 创建一个名为 modules 的目录,用于放置 JS 模块等资源文件
  • 创建模块文件,如 hello.js,用于编写 JS 模块相关代码
  • 创建一个名为 main.js 的入口文件,用于打包时设置 entry 属性
  • 创建 webpack.config.js 配置文件,使用 webpack 命令打包
  • 创建 HTML 页面,如 index.html,导入 WebPack 打包后的 JS 文件
  • 运行 HTML 看效果

hello.js

  需要将某些被其他js需要的方法导出(exports是ES5语法)

exports.sayHi = function () {
  document.write("<div>Hello WebPack</div>");
};

  如果需要将多个方法导出

var function01 = funciotn(){};
var function02 = function(){};
exports.function01 = function01;
方式1:直接一个一个的导出
exports.function02 = function02;
方式2:
exports = {function01,function02}    

main.js内容

  设置它为入口

  导入需要的js

var hello = require("./hello"); //导入hellow.js(可以不加后缀)
hello.sayHi();

webpack.config.js 的配置文件

  主要目的:将上面的两个js打包成一个js,由于main.js依赖了hellow.js,所以他们会打包在一块

module.exports = {
    entry: "./modules/main.js",
    output: {
        filename: "./js/bundle.js"
    }
};

HTML

  index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script src="dist/js/bundle.js"></script>
</body>
</html>

打包

# 用于监听变化
webpack --watch  //在webpack.config.js 中的配置可以省略watch=true配置

运行

运行 HTML 文件,你会在浏览器看到:

Hello WebPack

webpack实战(手动打包)

model01.js

var add = function (x, y) {
    return x+y;
}
var add2 = function (x, y) {
    return x+y+2;
}
module.exports.add = add;
// module.exports ={add,add2};//如果有多个方法这样导出
// module.exports.add2 = add2//如果有多个方法也可以这样导出

main.js(主文件)

//导入model01.js
var {add} = require("./model01.js")
var Vue = require("./vue.min.js")
var VM = new Vue({
    el:'#app',//vm接管了app区域的管理
    //model数据
    data:{
        num1:0,
        num2:0
    }
});

webpack.config.js(一定需要添加不然报错)

module.exports = {
    entry: "./main.js",
    output: {
        filename: "build.js"
    }
};

打包命令

webpack

效果  

webpack(自动打包)

  build.js并没有真正生成;

  推荐使用webpack-dev-server开发服务器,它的功能可以实现热加载并且,自动刷新浏览器。

  此时我们在开发中就可以不再使用nginx做服务器了

安装webpack-dev-server 

  使用 webpack-dev-server需要安装webpack、 webpack-dev-server和 html-webpack-plugin三个包。
cnpm install webpack@3.6.0 webpack-dev-server@2.9.1 html-webpack-plugin@2.30.1 --save-dev

配置webpack-dev-server

  安装完成,会发现程序目录出现一个package.json文件:此文件中记录了程序的依赖,node_modules:此文件存放了此项目的依赖包
  如果目录中没有package.json文件
npm init
  我们在package.json中添加(scripts是一个命令指令)
  "scripts": {
    "dev": "webpack-dev-server --inline --hot --open --port 5008"
  },
  • --inline:自动刷新
  • --hot:热加载
  • --port:指定端口
  • --open:自动在默认浏览器打开
  • --host:可以指定服务器的 ip,不指定则为127.0.0.1,如果对外发布则填写公网ip地址 

·  

配置webpack.config.js 

//引用html-webpack-plugin插件,作用是根据html模板(vue_02.html)在内存生成html文件,它的工作原理是根据模板文件在内存中生成一个index.html文件。
var htmlwp = require('html-webpack-plugin');
module.exports={
    entry:'./src/main.js',  //指定打包的入口文件
    output:{
        path: __dirname+'/dist',  // 注意:__dirname表示webpack.config.js(当前文件)所在目录的绝对路径(默认也是这个路径)
        filename:'build.js'		   //输出文件(没有真正的生成)
    },
    //devtool: 'eval-source-map',
    plugins:[
        new htmlwp({
            title: '首页',  //生成的页面标题<head><title>首页</title></head>
            filename: 'index.html', //webpack-dev-server在内存中生成的文件名称,自动将build注入到这个页面底部,才能实现自动刷新功能
            template: 'vue_02.html' //根据vue_02.html这个模板来生成(这个文件请程序员自己生成)
        })
    ]
}

启动webpack-dev-server

补充文件

vue_02.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue.js常用指令的测试</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="num1"/> +
    <input type="text" v-model="num2"/>=
    <span v-text="Number.parseInt(num1)+Number.parseInt(num2)"></span>
    <span v-text="result"></span>
    <button v-on:click="change">计算</button>
</div>
</body>
<!--<script src="vue.min.js"></script>-->
<!--<script src="dist/build.js"></script>-->
</html>

main.js

var {add} = require("./model01")
var Vue = require("./vue.min")
var VM = new Vue({
    el:'#app',//vm接管了app区域的管理
    data:{//model数据
        num1:0,
        num2:0,
        result:0
    },
    methods:{
        change:function () {
            //必须要有this(会修改data中的result数据)
            this.result = add(Number.parseInt(this.num1),Number.parseInt(this.num2))
        }
    }
});

model01.js

var add = function (x, y) {
    return x+y;
}
var add2 = function (x, y) {
    return x+y+2;
}
module.exports.add = add;
// module.exports ={add,add2};//如果有多个方法这样导出
// module.exports.add2 = add2//如果有多个方法也可以这样导出

  

webpack debug(调试)

1、在webpack.config.js中添加 devtool: 'eval-source-map',

2、在需要打上断点的js中添加debugger

    methods:{
        change:function () {
            debugger //调试
            this.result = add(Number.parseInt(this.num1),Number.parseInt(this.num2))
        }
    }

效果

原文地址:https://www.cnblogs.com/yanxiaoge/p/11103129.html