webpack基础
-
什么是webpack?
webpack是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具 -
webpack安装
- 全局安装:npm install webpack -g
- 安装到项目依赖中(在项目根目录):npm install webpack --save-dev
-
mac安装注意,需要root权限,如果安装不npm成功,可能就是国内网络问题,可以使用代理镜像如:npm config set registry http://registry.npm.taobao.org
-
浏览器目前解析不了ES6的代码,所以需要使用类似webpack这样的工具来使es6的代码转换成浏览器可以执行的代码
-
webpack 打包
- webpack ./src/main.js ./dist/bundle.js
- 命令 打包的文件 打包后存放的目录和名字
-
webpack可以做的事情
- 能够处理JS文件之间的互相依赖关系
- webpack能够处理JS的兼容问题,把高级的浏览器不识别的语法转为低级别的浏览器能识别的语法
-
示例:初步使用webpack隔行渐变功能
-
安装webpack遇到的问题
- 直接使用npm install webpack -g命令安装的时候,默认当前用户是没有权限的,需要使用sudo npm install webpack -g或者sudo npm install webpack -g --unsafe-perm=true --allow-root命令获取root权限安装
- 使用安装的时候会出现在 “node-gyp r” 卡住,需要手动安装node-gyp,建议使用淘宝的npm源,也可以使用cnpm -g install node-gyp进行安装node-gyp,然后重新执行sudo npm install webpack -g命令安装即可成功
- webpack打包前必须安装webpack-cli,使用npm install webpack-cli -g。注意安装的webpack-cli必须匹配webpack版本,否则也会出现异常。安装webpack-cli加版本号命令如:npm install webpack@3.0.0 -g
-
webpack配置文件的使用
- 在当前项目根目录,创建webpack.config.js
- 有了配置文件以后,就可以直接使用webpack命令打包
-
使用webpack-dev-server来自动实现打包编译的功能
- 运行npm install webpack-dev-server -D 把这个工具安装到项目的本地开发依赖
- 安装完毕,这个工具的用法和webpack命令的用法,完全一样
- 由于我们是在项目中,本地安装的webpack-dev-server,所以无法把它当做脚本命令,在shell终端直接运行;(只有那些安装到全局 -g的功能句,才能在终端中正常执行)
- 在package.json 中scripts中添加"dev":"webpack-dev-server",然后执行命令:npm run dev。
- 注意:webpack-dev-server这个工具,如果想要正常运行,要求在本地项目中必须安装webpack,使用命令:npm install webpack -D
- webpack-dev-server帮我们打包生成的bundle.js文件,并没有存放到实际的物理磁盘上,而是,直接托管到了电脑的内存中,所以我们在项目根目录中,根本找不到这个打包好的bundle.js
- 我们可以认为webpack-dev-server把打包好的文件,以一种虚拟的形式,托管到了咱们项目的根目录中,虽然我们看不到它,但是可以认为它和dist,src,node_modules平级,有一个看不见的文件叫做bundle.js。在需要引用js的文件的地方引用方式就是/bundle.js
- webpack命令配置参数一:在package.json 中scripts中添加"dev":"webpack-dev-server --open --port 3000 --contentBase src --hot" 。
- webpack命令配置参数二:在webpack.config.js中exports下添加:devServer:{
open: true,//自动打开浏览器
port: 3000,//设置启动时候运行的端口
contentBase: 'src', //指定托管的根目录
hot: true //启用热更新第1步
}
const webpack = require('webpack'); // 热更新的第2步
plugins:[ //配置插件节点
new webpack.HotModuleReplacementPlugin() //new 一个热更新的模块对象,启用热更新的第三步
] - 将html页面放入内存中
1.npm install html-webpack-plugin -D
2.在webpack.config.js中
const htmlWebpackPlugin = require('html-webpack-plugin')
在plugins节点中
new htmlWebpackPlugin({
template: path.join(__dirname,'./src/index.html'),//指定模板页面,将来根据指定的路径页面,去生成内存中的页面
filename: 'index.html' //内存中的页面名称
})
3.当使用html-webpack-plugin之后,我们不需要再手动引入bundle.js文件了,因为这个插件已经帮我们自动引入内存中的bundle.js
-
css加载器
- 注意:webpack默认只打包处理js类型的文件,无法处理其他的非js类型的文件
- 如果要处理费Js类型的文件,我们需要手动安装一些合适的第三方Loader加载器
- 如果要打包处理css文件,需要安装cnpm install style-loader css-loader -D
- 打开webpack.config.js这个配置文件,在里面新增一个配置节点,叫做module,它是一个对象;在这个module对象身上,有一个rules属性,这个rules属性是一个数组,在这个数组中存放了所有第三方文件的匹配和处理规则
- 在webpack.config.js配置对象代码示例:
module:{ //这个节点配置所有第三方的加载器 rules:[ {test: /\.css$/, use:['style-loader','css-loader']}, // 配置处理.css文件 {test: /\.less$/, use: ['style-loader','css-loader','less-loader']}, //配置处理.less文件的第三方loader规则 {test"/\.cscss$/, use: ['style-loader','css-loader','sass-loader']}, //配置处理.scss文件的第三方loader规则 {test"/\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=7631&name=[hash:8]-[name].[ext]'}, //配置处理图片路径的第三方loader规则,limit设置图片大小,如果引用的图片小于给定值使用base64编码字符串,否则使用图片路径。 {test"/\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'},// 处理字体文件的loader ] }
- 在main.js中使用css:
import 'path/name.css'
-
webpack处理第三方文件类型的过程:
- 发现这个处理的文件不是JS,然后就去webpack.config.js配置文件中,查找有没有对应的第三方loader规则
- 如果找到规则,就会调用对应的Loader处理这种文件类型
- 在调用Loader的时候,是从后往前调用的
- 当最后一个Loader调用完毕,会把处理的结果,直接交给webpack进行打包合并,最终输出到bundle.js中去
-
配置处理less文件
- npm install less -D
- npm install less-loader -D
-
配置处理scss文件
- npm install node-sass -D
- npm install sass-loader -D
-
初始化项目:npm init -y 。如果包名含有中文,不能使用-y 。尽量不使用中文的包名
-
由于webpack是基于Node进行构建的,所以webpack的配置文件中,任何合法的node代码都是支持的
-
webpack中使用url-loader处理字体文件
- 默认情况下,webpack无法处理css文件中的url地址,不管是图片还是字体库。只要是url地址都处理不了
- 安装loader: npm install url-loader file-loader -D
- 使用url-loader处理字体文件
- npm install bootstrap -S
- 如果要通过路径的形式,去引入node_modules中相关的文件,可以直接省略路径前面的node_modules这一层目录,直接写包的名称,然后后面跟上具体的文件路径
-
webpack中的babel的配置
- class关键字是ES6中提供的新语法,用来创建ES6中面向对象编程方式。class是从后端语言中借鉴过来实现面向对象
- static 关键字,可以定义静态属性,可以通过类名直接访问
- 在webpack中,默认只能处理一部分ES6语法或者ES7语法,一个更高级的语法webpack是处理不了的;这时候,就需要借助第三方loader来帮助webpack处理这些高级的语法,当第三方loader把语法转为低级语法之后,会把结果交给webpack去打包到bundle.js中。
- 通过Babel可以帮我们将高级语法转换为低级语法。在webpack中,可以运行如下两套命令,安装两套包去安装babel相关的loader功能
- 安装第一套包:npm install babel-core babel-loader babel-plugin-transform-runtime -D
- 安装第二套包:npm install babel-preset-env babel-preset-stage-0 -D
- 打开webpack的配置文件,在module节点下的rules数组中,添加一个新的匹配规则。配置规则时必须把node_modules排除掉:如果不排除,Babel会把node_modules中素有的第三方JS文件,都打包编译,这样会非常消耗CPU,同时打包非常慢。如果不排除,node_module中的js被转换了也无法正常运行:
{ test:/\.js$/, use: 'babel-loader', exclude:/node_modules/ } //转换ES高级语法
- 在项目目录中,新建一个较重.babelrc的Babel配置文件,这个是json格式文件,内容必须符合JSON语法规范,不能写注释,字符必须使用双引号
- .babelrc中配置如下:
{ "presets": ["env","stage-0"], "plugins":["transform-runtime"] }
- 目前我们安装的babel-preset-env是比较新的ES语法插件,之前安装的是babel-preset-es2015。现在出了一个更新的语法插件babel-preset-env,它包含了所有和es**相关的语法
-
使用Vue实例的render方法渲染组件
- 在页面中渲染基本的组件(component)
- 在页面中使用render函数渲染组件
-
在普通网页中使用vue
- 使用script标签,引入vue包
- 在index页面中,创建一个id为app的div容器
- 通过new vue 得到一个vm的实例
-
在webpack中使用vue
- 安装包vue包:npm install vue -S
- 使用vue示例代码:
import Vue from 'vue' // 这个引入方式无法正常执行
import Vue from '../node_modules/vue/dist/vue.js' //这种引入方式可以正常执行
import login from './login.vue' // 导入vue模板
var vm = new Vue({
el: '#app', //指定容器,需要在页面中顶一个id为app的div
data: {
msg: '123'
},
components:{ //在webpack中无法使用组件方式,展示vue模板
login
},
render: function(createElements){ // 在webpack 中,如果想通过vue,把一个组件放到页面中去展示,vm 实例中的render函数可以实现
return createElements(login)
}
render: c => c(login) //render简写
})
- 注意:在webpack中,使用import Vue from 'vue'都的Vue构造函数,功能不完整,只提供了runtime-only的方式并没有提供像网页中那样的使用方式。解决这个问题,可以使用两种方式:
- 修改导入包:import Vue from '../node_modules/vue/dist/vue.js'
- 不修改导入包(推荐),在webpack.config.js中添加新的模块
resolve: {
alias:{
"vue$": "vue/dist/vue.js", //修改vue被导入时候的包的路径
}
}
- .vue文件定义组件模板对象内容:
- html内容在<template></template>中
- js业务逻辑在<sccript></sccript>中
- 样式内容在<style></style>中
- 使用webpack处理.vue文件,需要在webpack.config.js中配置加载插件,否则无法解析.vue文件中的内容
- 添加加载插件:const VueLoaderPlugin = require('vue-loader/lib/plugin');
- 在plugins添加定义的插件:new VueLoaderPlugin()
- webpack如果要打包处理.vue文件,需要一些操作:
- 需要安装相关的loader: npm install vue-loader vue-template-compiler -D
- 在配置文件中,新增loader配置项:{test:/.vue$/, use: 'vue-loader'}
- 向外暴露成员的方式
- node中向外暴露成员的方式:module.exports = {},使用require导入
- ES6中:使用export default和export向外暴露成员,使用import导入
- export default {},可以使用任意变量来接收。而且在同一个js文件中只能使用一次export default来暴露成员变量
- 在一个js文件中可以同时使用export default和export暴露成员变量
- 使用export向外暴露的成员,只能使用{}的形式接收,这种形式叫做按需导出。
- export可以向外宝暴露多个成员,同时如果某些成员,我们在import的时候不需要,则可以不在{}中定义
- 使用export导出的成员,必须严格按照导出时的名称在{}按需导入
- 使用export导出的成员,如果就想换个名称来接收,可以使用as来启别名
- 结合webpack使用vue-router
- 安装vue-router: npm install vue-router
- 导入vue-router: import VueRouter from 'vue-router'
- 手动安装vueRouter: Vue.use(VueRouter)
- 使用:
var router = new VueRouter({ routes: [ //acount goodslist { path: '/account',component: account } { path: '/goodslist',component: goodslist } ] }) var vm = new Vue({ el: '#app', render: c => c(app), //render会把el中指定的容器中的内容都清空,所以不要把router-view和router-link直接填写到el中 router //将路由挂载到vm上 }) //html中使用组件 <div id="app"> <router-link to="/account">Account</router-link> <router-link to="/goodslist">goodslist</router-link> <router-view></router-view> </div>
- app这个组件是通过VM实例的render函数,render函数如果需要渲染组件,渲染出来的组件,只能放到el:'#app'所指定的元素中
- Account和Goodslist组件,是通过路由匹配监听到的,所以这两个组件,只能展示到属于路由的<router-view></router-view>中去
- 结合webpack实现children子路由(路由嵌套)
- vsCode安装vue插件Vetur和 Vue 2 Snippets
import login 'sub/login.vue' import login 'sub/register.vue' var router = new VueRouter({ routes: [ //acount goodslist { path: '/account',component: account, children: [ {path: 'login',component: login}, {path: 'register',component: register} ] }, { path: '/goodslist',component: goodslist } ] })
- 组件中style标签属性和scoped属性的介绍
- 使用
<style scoped> div { color:red } </style>
- 普通的style标签只支持普通的样式,如果要启用scss或less需要为style元素设置lang属性
<style lang="scss" scoped> body { div{ color: red } } </style>
- 只要咱们的style标签,是在.vue组件中定义的,那么推荐都为style开启scoped属性
- webpack路由嵌套
- 创建router.js。将所有路由相关js都移动到这个文件中统一管理
- 在router.js中添加: export default router
- 导入路由 import router from './router.js'
网友评论