从前端模块化 到 webpack 再到使用 vue文件 前端代码复杂化带来的问题 使用闭包方式解决全局变量同名问题 模块化规范 webpack的基本使用 各种各样的loader 使用vue.js并用webpack打包 抽取vue的template 封装 .vue 文件

在网页开发的早期,js作为一种脚本语言,做一些简单的表单验证或者动画实现等,代码较少

随着ajax异步请求的出现,慢慢形成了前后端的分离

导致客户端要完成的事情越来越多,代码量也与日俱增

为了应付代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护

但是这种方式,仍不能避免一些问题(例如全局变量同名)

使用闭包方式解决全局变量同名问题

每个人开发的每个模块的代码,都放到闭包里,闭包返回需要共用的数据,用变量接收

这样只需要保证每个文件的变量名不冲突即可

let modelXXX= (function(){
    ......

    return obj;
})();

模块化规范

CommonJS

导出:

module.exports = {
	......
}

导入:

let {a, b, c } = require('moduleA')

// 等价于
let moduleA = require('moduleA')
let a = moduleA.a;
let b = moduleA.b;
let c = moduleA.c;

ES6 module

使用ES6模块的时候,引入到页面时需要修改script的type,
设置type为module,就可以避免命名冲突的问题
这样每一个模块都有自己的空间,不能随意访问其他模块的内容

如果要想自己的东西能够被别的地方使用,可以使用 export 导出

export {a, b, c}

别的地方要使用的时候可以导入

import {a, b, c} from 'xxxxx.js'

导出方式2:在定义变量的同时进行导出

export var num = 10;  

也可以导出函数、类等

某些情况下,一个模块中包含某个功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名,这时就可以使用 export default,一个模块只能由一个default

这样导入default的东西就不加大括号了,而且可以自己命名

如果一次性要导入的东西太多,可以这么写

import * as xxx from 'xxx'

其他

AMD、CMD

webpack的基本使用

什么是webpack

从本质上来讲,webpack是一个现代的JavaScript应用的静态模块打包工具

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

与grunt/gulp 的区别

  • grunt、gult更加强调的是前端流程的自动化,模块化不是核心
  • webpack更加强调模块化开发管理,其他的是它附带的功能

webpack安装

全局安装:npm install webpack@3.6.0 -g

注:这里使用 3.6.0 版本是因为 vue cli2 依赖该版本

webpack —version

局部安装: 添加属性 --save-dev

当在package.json中定义了scripts时,如果其中包含了webpack命令,那么会优先使用本地的webpack,而不是全局的webpack

使用命令指定打包文件

webpack main.js bundle.js

webpack会将main.js打包成bundle.js,在打包main.js是会自动分析有没有其他依赖,然后自动处理这些依赖

根据webpack配置文件打包

基本配置,新建webpack.config.js,写入以下配置,然后就可以使用webpack来打包

var path = require('path')
const webpack = require('webpack')

module.exports = {
    // 入口
    entry: './src/main.js',
    output: { // 出口
        // path: './dist', // 不能写相对路径,需要动态获取
        path: path.resolve(__dirname, 'dist'),
        filename: 'bytc.js',
        publicPath: 'dist/'
    }
}

也可以在package.json添加build脚本:
从前端模块化 到 webpack 再到使用 vue文件
前端代码复杂化带来的问题
使用闭包方式解决全局变量同名问题
模块化规范
webpack的基本使用
各种各样的loader
使用vue.js并用webpack打包
抽取vue的template
封装 .vue 文件
然后使用 npm run build 来进行打包

各种各样的loader

webpack配置文件中添加一个module属性,下面定义rule属性,声明转换的规则

css

npm install --save-dev css-loader
npm install style-loader --save-dev
{
    test: /.css$/,
    // 也可以直接写 use: ['style-loader', 'css-loader]
    use: [
        { loader: "style-loader" },
        { loader: "css-loader" }
    ]
},

less

npm install --save-dev less-loader less
{
    test: /.less$/,
    use: ['style-loader','css-loader', 'less-loader']
},

sass

npm install sass-loader node-sass webpack --save-dev
{
    test: /.scss$/,
    use: ['style-loader', 'css-loader', 'sass-loader']
},

image

npm install --save-dev url-loader
npm install --save-dev file-loader
{
    test: /.(png|jpg|gif)$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                // 当图片小于limit时,会被编译成base64字符串形式
                // 当图片大于limit时,需要使用file-loader模块进行加载
                // limit默认是 8196
                limit: 13000,
                name: 'images/[name]-[hash:8].[ext]'
            }
        }
    ]
},

图片转换之后可以指定发布路径,通过module的output的publicPath属性:

output: {
    // path: './dist', // 不能写相对路径,需要动态获取
    path: path.resolve(__dirname, 'dist'),
    filename: 'bytc.js',
    publicPath: 'dist/'
},

从前端模块化 到 webpack 再到使用 vue文件
前端代码复杂化带来的问题
使用闭包方式解决全局变量同名问题
模块化规范
webpack的基本使用
各种各样的loader
使用vue.js并用webpack打包
抽取vue的template
封装 .vue 文件

es6语法处理

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

rule:

{
		test: /.js$/,
		exclude: /(node_modules|bower_components)/,
		use: {
		    loader: 'babel-loader',
		    options: {
		        presets: ['es2015']
		    }
		}
}

使用vue.js并用webpack打包

我们首先使用npm来安装vue:npm install vue --save

我们在入口js脚本里引入vue:

import Vue from 'vue'

new Vue({
    el: '#app',
})

其中,在index.html中要定义一个id是app的div和这个Vue实例进行对应

从前端模块化 到 webpack 再到使用 vue文件
前端代码复杂化带来的问题
使用闭包方式解决全局变量同名问题
模块化规范
webpack的基本使用
各种各样的loader
使用vue.js并用webpack打包
抽取vue的template
封装 .vue 文件

然后,使用webpack打包即可

但是,打包之后发现,网页打开报错?

原因是,会生成两种vue代码

runtime-only:代码中,不可以有任何的template

runtime-compile:代码中可以有template,因为有compiler可以用来编译template

如果要使用compile的类型,要在webpack中添加以下配置:
从前端模块化 到 webpack 再到使用 vue文件
前端代码复杂化带来的问题
使用闭包方式解决全局变量同名问题
模块化规范
webpack的基本使用
各种各样的loader
使用vue.js并用webpack打包
抽取vue的template
封装 .vue 文件

再次打包即可

抽取vue的template

虽然直接引入vue可以进行使用,但是这样的话,会导致入口脚本的Vue实例中会有很多很多代码,index.html的app div也会很复杂

我们想要的是,index.html的结构很简单,入口脚本的结构也很简单

我们可以先定义一个App组件,然后在vue实例中使用template属性中使用这个组件,这时template会替换 el 选项指定的div

然后,将这个App组件抽离出去,放到一个单独的js脚本中,在入口脚本引入这个组件脚本即可

从前端模块化 到 webpack 再到使用 vue文件
前端代码复杂化带来的问题
使用闭包方式解决全局变量同名问题
模块化规范
webpack的基本使用
各种各样的loader
使用vue.js并用webpack打包
抽取vue的template
封装 .vue 文件

我们可以新建一个文件夹专门存放声明组件的js文件,这样会很方便管理

封装 .vue 文件

虽然上面把组件抽离出来,使入口文件和index.html变的简单了,但是抽离出的组件写起来仍然很麻烦

原因是,抽取出去的是js文件,里面要声明一些template的东西很麻烦

这个时候就需要使用vue文件了,.vue文件中可以把template,script、style分开来写

然后像引入js文件一样引入vue文件即可

要使用vue还需要安装vue-loader和vue-template-compiler

npm install vue-loader vue-template-compiler --save-dev

然后添加webpack规则:

{
		test: /.vue$/,
		use: ['vue-loader']
}

vue-laoder大于13的版本,使用时还需要配置一个插件

如果不想配置插件,就将版本改成13就可以了 "vue-loader": "^13.0.0"