搭建vue脚手架
注意:
1.使用npm 的方式安装并引入vue时,需要用render函数,否则页面会是空白。使用下载的vue文件引入就可以不写render函数,在html文件里写vue模板代码。
安装步骤:
1.安装webpack,webpack-cli
yarn add webpack webpack-cli --dev
2.安装热更新
yarn add webpack-dev-server --dev
基本配置参数:
devServer:{ host:'localhost', port:8080,//设置端口号 contentBase:path.join(__dirname,'./dist'),//设置url的根目录,如果不设置,则默认是指向项目根目录 historyApiFallback : true,//让所有404的页面定位到index.html hot:true,//启动热更新,有的博客说必须搭配new webpack.HotModuleReplacementPlugin()插件,但是好像使用webpack-dev-server直接就可以热更新了。还没弄清楚HotModuleReplacementPlugin的用法 inline: true,//实时刷新,webpack-dev-server有两种模式可以实现自动刷新和模块热替换机制 1. Iframe mode(默认,无需配置)页面被嵌入在一个iframe里面,并且在模块变化的时候重载页面 2.inline mode(需配置)添加到bundle.js中,当刷新页面的时候,一个小型的客户端被添加到webpack.config.js的入口文件中 compress:true,//Enable gzip compression for everything served overlay: true, //Shows a full-screen overlay in the browser stats: "errors-only" ,//To show only errors in your bundle open:true, //When open is enabled, the dev server will open the browser. proxy: { "/api": { target: "http://localhost:3000", pathRewrite: {"^/api" : ""} } },//重定向 },
historyApiFallback
这个配置属性是用来应对返回404页面时定向到特定页面用的
语法是向historyApiFallback对象中的rewrites属性传一个对象格式,如下:
historyApiFallback:{ rewrites:[ {from:/./,to:'/404.html'} ] }
hot
热模块替换机制
hot:true
注意,如果你的项目中使用了热模块替换机制,HotModuleReplacementPlugin插件会自动添加到项目中,而不需要再在配置文件中做添加。
compress
这是一个布尔型的值,当它被设置为true的时候对所有的服务器资源采用gzip压缩
采用gzip压缩的优点和缺点:
优点:对JS,CSS资源的压缩率很高,可以极大得提高文件传输的速率,从而提升web性能
缺点:服务端要对文件进行压缩,而客户端要进行解压,增加了两边的负载
overlay
用于在浏览器输出编译错误的,默认是关闭的,需要手动打开:
overlay: true
如果你想江warnings一同打印出来,可设置:
overlay: {
warnings: true,
errors: true
}
stats
这个配置属性用来控制编译的时候shell上的输出内容,因为我们并不需要所有的内容,而只是需要部分的如errors等
在shell中只输出errors:
stats: "errors-only"
open
当open选项被设置为true时,dev server将直接打开浏览器
proxy
重定向是解决跨域的好办法,当后端的接口拥有独立的API,而前端想在同一个domain下访问接口的时候,可以通过设置proxy实现。
如果后端接口地址是10.10.10.10:3000,你可以这样设置:
proxy: {
"/api": "http://10.10.10.10:3000"
}
一个 “/api/users”地址的请求将被重定向到”http://10.10.10.10:3000/api/users“,如果不希望”api”在传递中被传递过去,可以使用rewrite的方式实现:
proxy: { "/api": { target: "http://localhost:3000", pathRewrite: {"^/api" : ""} } }
publicPath
用于设置编译后文件的路径,假设服务器的运行地址是 http://localhost:8080,输出文件名设置为bundle.js,那么默认情况下publicPath是”/”,因此文件地址为http://localhost:8080/bundle.js 如果想要设置为别的路径可以这样:
publicPath: "/assets/"
设置后文件地址为:http://localhost:8080/assets/bundle.js
注意:
确保publicPath的书写规则:前后都有一个斜杠!
3.新建webpack.config.js基本配置文件,在配置文件里进行初始化
const path=require('path');config={ entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } }; module.exports=config;
4.在package.json配置dev指令
"dev": "webpack-dev-server --open --config webpack.config.js", //热更新在浏览器中打开页面,读取配置文件 "build": "webpack --config webpack.config.js" //打包成文件夹
5.在项目中添加模板文件,如果有index.html文件,项目会默认使用index.html文件作为模板。如果没有项目热启动会生成一个项目目录页面。
还可以使用html-webpack-plugin插件指定模板文件及根据模板文件生成的文件的文件名,并将生成的文件一起打包到输出的文件夹中(dist/)。
安装html-webpack-plugin
yarn add html-webpack-plugin --dev
在配置文件中添加设置:
var HtmlwebpackPlugin=require('html-webpack-plugin'); plugins:[ new HtmlwebpackPlugin({ filename:'index.html', template:'./index.html', inject:false }), ]
6.安装css-loader,style-loader,解析导入的css文件
yarn add css-loader style-loader --dev
修改配置文件
1 module:{ 2 rules:[ 3 { 4 test:/\.css$/, 5 use:['style-loader','css-loader'] 6 7 } 8 ] 10 }
7.安装extract-text-webpack-plugin ,合并css(会导致css修改不会触发热更新)
yarn add extract-text-webpack-plugin --dev
将css文件及文件中的css合并到一个css文件中,不用的时候引入的css和写的样式并不会打包在一个css文件中
修改配置文件
const ExtractTextPlugin=require(extract-text-webpack-plugin); module:{ rules:[ { test:/\.css$/, use:ExtractTextPlugin.extract({ use:'css-loader', fallback:'style-loader' }) } ] } //在plugin中实例化,将css打包到main.css文件下,文件会被打包到设置的输出文件夹的下面 plugins:[ new ExtractTextPlugin("main.css") ]
8.安装url-loader,file-loader,解析图片,文件等资源的引入
补充说明:?limit=1024表示的作用是:
当遇到.gif、.png、.ttf等格式文件时,url-loader会把它们一起编译到dist目录下,“?limit=1024”是指如果这个文件小于1kb,就以base64的形式加载,不会生成一个文件
yarn add url-loader file-loader --dev
在配置文件中设置loader:
module:{ rules:[ { test:/\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader:'url-loader?limit=1024 } ] }
9.安装vue及相关loader,在用vue进行单文件开发的时候需要解析vue文件及css和模板解析。但是貌似安装vue-loader的时候会自动安装vue-style-loader
vue-loader 会解析文件,提取每个语言块,如有必要会通过其它 loader 处理(比如<script>默认用babel-loader处理,<style>默认用style-loader处理),最后将他们组装成一个 CommonJS 模块,module.exports 出一个 Vue.js 组件对象。
vue-loader 支持使用非默认语言,比如 CSS 预处理器,预编译的 HTML 模版语言,通过设置语言块的 lang 属性。例如,你可以像下面这样使用 Sass 语法编写样式(需要安装node-sass sass-loader):
<style lang="sass"> /* write Sass! */ </style>
说明:vue-loader在编译.vue文件时,会对<template>、<script>、<style>分别处理,所以在vue-loader选项里多了一项options来进一步对不同语言进行配置(后续会对option进行说明)
yarn add vue vue-loader vue-style-loader vue-template-compiler --dev
安装vue-hot-reload-api 。修改vue文件的时候会刷新页面,安装vue热加载可以局部刷新。不需配置
yarn add vue-hot-reload-api --dev
配置文件:
const VueLoaderPlugin=require("vue-loader/lib/plugin"); module:{ rules:[ { test:/\.vue$/, loader:'vue-loader' } ] } //在plugin中实例化,将css打包到main.css文件下,文件会被打包到设置的输出文件夹的下面 plugins:[ new VueLoaderPlugin() ]
10.安装babel,转换es6语法,babel-preset-env会将es6语法转换成es5语法,如果要使用es6中新的内置对象比如 Promise
或者 WeakMap
, 静态方法比如 Array.from
或者 Object.assign
, 实例方法比如 Array.prototype.includes
和生成器函数(提供给你使用 regenerator 插件)还需要安装polyfill
yarn add babel babel-loader babel-core babel-preset-env --dev
yarn add babel-polyfill --dev
你需要在你的应用入口顶部通过 require 将 polyfill 引入进来。
确保它在任何其他代码/依赖声明之前被调用!
在 webpack.config.js
中,将 babel-polyfill
加到你的 entry 数组中:
require("babel-polyfill"); module.exports = { entry: ["babel-polyfill", "./app/js"] };
也可以使用babel-plugin-transform-runtime或babel-runtime代替babel-polyfill。
注意:安装以后可能会报版本错误:
所以下载对应的版本就是了,下面是安装babel-core 7.x的方法
npm install -D @babel/core
创建.babelrc文件:
{ "presets": [ "env" ] }
扩展:
使用scss
安装node-sass sass-loader
yarn add node-sass sass-loader --dev
配置文件:
module:{ rules:[{ test:/\.scss$/, use:['style-loader','css-loader','sass-loader'] }] } 在.vue文件中使用需要在style标签中添加lang="scss"或lang="sass"属性
babel-loader,babel-core,babel-polify,babel-plugin-transform-runtime之间的关系
babel-core在npm官网中的解释是
Babel compiler core.
也就是Babel编译器的核心,因此意味着如果要使用babel-loader进行es6的转码你首先必须得安装babel-core
npm install --save-dev babel-core
babel-core安装了就行,无需手动配置和引入。
搞懂了babel-loader和babel-core的关系,那babel-polify和babel-plugin-transform-runtime又是啥呢?
由于Babel默认只转换新的javascript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。
因此,如果你的代码中用到了这些API那么你需要一个垫片库,babel polyfill就是这个作用。
babel polyfill有三种:
* babel-runtime
* babel-plugin-transform-runtime
* babel-polyfill
transform-runtime在使用webpack打包时需要配置到 .babelrc文件的的plugins中
"plugins": [
["transform-runtime", {
"helpers": false,
"polyfill": true,
"regenerator": true,
"moduleName": "babel-runtime"
}]
]
后面的配置项不设置都将默认为true,其实可以完全像下面这样配置
"plugins": ["transform-runtime"]
babel-runtime和babel-plugin-transform-runtime的区别是使用babel-runtime时每次要转码一个api都需要手动添加
require('babel-runtime');
而babel-plugin-transform-runtime会由工具自动添加,主要的功能是为api提供沙箱的垫片方案,不会污染全局的api。
最后,babel-polyfill则是通过修改全局prototype来实现API的垫片的,因此比较适合用在单独运行的项目中。
webpack-dev-serve热更新问题:
webpack-dev-server有热更新功能,当webpack的js文件被修改,则会自动更新数据并刷新浏览器。
热加载:
if (module.hot) { module.hot.accept(); }
这段代码用于标志哪个模块接收热加载,如果是代码入口模块的话,就是入口模块接收。
当修改文件时,Webpack 会从修改模块开始根据依赖关系往入口方向查找热加载接收代码。如果没有找到的话,默认是会刷新整个页面的。如果找到的话,会替换那个修改模块的代码为修改后的代码,并且从修改模块到接收热加载之间的模块的相关依赖模块都会重新执行返回新模块值,替换点模块缓存。
由于 Webpack 的热加载会重新执行模块,如果是使用 React,并且模块热加载写在入口模块里,那么代码调整后就会重新执行 render。但由于组件模块重新执行返回了新的组件,这时前面挂载的组件状态就不能保留了,效果就等于刷新页面。
需要保留组件状态的话,需要使用 react-hot-loader 来处理。
css 问题
如果使用style-loader将样式添加到js文件中,在编写样式的时候可以享受热更新的效果,如果使用extract-text-webpack-plugin 将样式提取,此组件并不支持热更新。只会重新打包但是并不会刷新页面。
官方建议在开发环境中关闭ExtractText组件。
html 问题
html-webpack-plugin 创建html 并不经过entry的入口,并没有在热更新的检测范围,所以并没有热更新
总结:css 和 html 没有热更新的原因是没有进入到entry 入口,不在热跟新的检测范围内。