前端代码复杂化带来的问题
在网页开发的早期,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脚本:
然后使用 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/'
},
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代码
runtime-only:代码中,不可以有任何的template
runtime-compile:代码中可以有template,因为有compiler可以用来编译template
如果要使用compile的类型,要在webpack中添加以下配置:
再次打包即可
抽取vue的template
虽然直接引入vue可以进行使用,但是这样的话,会导致入口脚本的Vue实例中会有很多很多代码,index.html的app div也会很复杂
我们想要的是,index.html的结构很简单,入口脚本的结构也很简单
我们可以先定义一个App组件,然后在vue实例中使用template属性中使用这个组件,这时template会替换 el 选项指定的div
然后,将这个App组件抽离出去,放到一个单独的js脚本中,在入口脚本引入这个组件脚本即可
我们可以新建一个文件夹专门存放声明组件的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"