DIV Vue-cil腳手架

webpack

webpack是一個現代JavaScript應用程序的靜態模塊打包器。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖(dependency graph),其中包含應用程序須要的每一個模塊,而後將全部這些模塊打包成一個或多個 bundlejavascript

歷史介紹

  • 2009年初,commonjs規範還未出來,此時前端開發人員編寫的代碼都是非模塊化的,
    • 那個時候開發人員常常須要十分留意文件加載順序所帶來的依賴問題
  • 與此同時 nodejs開啓了js全棧大門,而requirejs在國外也帶動着前端逐步實現模塊化
    • 同時國內seajs也進行了大力推廣
    • AMD 規範 ,具體實現是requirejs define('模塊id',[模塊依賴1,模塊依賴2],function(){ return ;}) , ajax請求文件並加載
    • Commonjs || CMD 規範seajs 淘寶玉伯
      • commonjs和cmd很是類似的
        • cmd require/module.exports
      • commonjs是js在後端語言的規範: 模塊、文件操做、操做系統底層
      • CMD 僅僅是模塊定義
    • UMD 通用模塊定義,一種既能兼容amd也能兼容commonjs 也能兼容瀏覽器環境運行的萬能代碼
  • npm/bower集中包管理的方式備受青睞,12年browserify/webpack誕生
    • npm 是能夠下載先後端的js代碼475000個包
    • bower 只能下載前端的js代碼,bower 在下載bootstrap的時候會自動的下載jquery
    • browserify 解決讓require能夠運行在瀏覽器,分析require的關係,組裝代碼
    • webpack 打包工具,佔市場主流
(function (root, factory) {  
    if (typeof exports === 'object') { 
        module.exports = factory();  //commonjs環境下能拿到返回值
    } else if (typeof define === 'function' ) {  
        define(factory);   //define(function(){return 'a'})  AMD
    } else {  
        window.eventUtil = factory();  
    }  
})(this, function() {  
    // module  
    return {  
        //具體模塊代碼
        addEvent: function(el, type, handle) {  
            //...  
        },  
        removeEvent: function(el, type, handle) {  
              
        },  
    };  
});

模塊實現

1.下載webpack爲項目開發依賴

npm install webpack@3.12.0 -Dcss

2.建立main.js做爲項目的入口文件
// 整個程序的入口文件

import Vue from './vue.js'
import App from './App.js'
// 模塊總體加載
// import {num,num2,add} from './App.js'

// console.log(num);
// console.log(num2);
// add(3,5);

// import * as object from './App.js'
// console.log(object);
// console.log(object.num);
// console.log(object.num2);
// add(3,5);
new Vue({
    el:'#app',
    components:{
        App
    },
    template:`<App />`
});
3.建立一個App.js
var App = {
    template:`
        <div>
            我是一個入口組件
        </div>
    `
};
//1. 聲明並導出
export var num = 2; //做爲一整個對象key導出

//2. 聲明再導出
var  num2 = 4;
export {num2};
//3.拋出一個函數
export function add(x,y) {
    return console.log(x+y);
}
//4.拋出一個對象
export default App;
4.在package.json文件中配置以下:
{
  "name": "29_module",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "build": "webpack ./main.js ./build.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.12.0"
  }
}
5.新建一個index.html,script腳本引入打包完成的build.js以下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div id="app"></div>
    <script type="text/javascript" src="./build.js"></script>
    
</body>
</html>

webpack 編譯以後的build.js文件解讀

關於setimmediate介紹連接:html

http://www.ruanyifeng.com/blog/2014/10/event-loop.html前端

webpack打包模塊的源碼 執行順序
  • 1:把全部模塊的代碼放入到函數中,用一個數組保存起來
  • 2:根據require時傳入的數組索引,能知道須要哪一段代碼
  • 3:從數組中,根據索引取出包含咱們代碼的函數
  • 4:執行該函數,傳入一個對象 module.exports
  • 5:咱們的代碼,按照約定,正好是用module.exports = 'xxxx' 進行賦值
  • 6:調用函數結束後,module.exports從原來的空對象,就有值了
  • 7:最終return module.exports; 做爲require函數的返回值

webpack.config.js文件配置

  • entry 是一個對象,程序的入口
    • key:隨意寫
    • value: 入口文件
  • output 是一個對象,產出的資源
    • key: filename
    • value : 生成的build.js
  • module 模塊(對象)
    • loaders:[]
      • 存在一些loader `{ test:正則,loader:'style-loader!css-loader' }
配置文件webpack.config.js的修改

修改配置文件名爲:webpack.dev.config.js和webpack.prod.config.jsvue

在package.json文件中修改
"scripts": {
     "dev": "webpack --config ./webpack.dev.config.js",
     "prod": "webpack --config ./webpack.prod.config.js"

}

css文件處理

es6模塊導入
import './main.css'
編譯以後報錯

對於webpack來講,css文件也是一個模塊,可是像這樣的文件,webpack得須要loaders去處理這些文件java

下載並配置

npm i css-loader style-loader -Dnode

module:{
        loaders:[
            {   
                // 遇到後綴爲.css的文件,webpack先用css-loader加載器去解析這個文件
                // 最後計算完的css,將會使用style-loader生成一個內容爲最終解析完的css代碼的style標籤,放到head標籤裏。
                // webpack在打包過程當中,遇到後綴爲css的文件,就會使用style-loader和css-loader去加載這個文件。
                test:/\.css$/,
                loader:'style-loader!css-loader'
            }
            ]
}

圖片文件的處理

App.js 導入圖片資源
import imgSrc from './myGirl.jpg'

export default{
    template:`
        <div>
            <img :src="imgSrc" alt="" />
        </div>
    `,
    data(){
        return {
            imgSrc:imgSrc
        }
    }
};

對文件的處理,webpack得須要url-loaderfile-loaderjquery

下載處理圖片的loader模塊

npm i url-loader file-loader -Dwebpack

添加loader的配置
module:{
        loaders:[
            {
                test:/\.css$/,
                loader:'style-loader!css-loader'
            },
            {
                test:/\.(jpg|png|jpeg|gif|svg)$/,
                loader:'url-loader?limit=4000'
            }
        ]
    },
webpack最終會將各個模塊打包成一個文件,所以咱們樣式中的url路徑是相對入口html頁面的,而不是相對於原始css文件所在的路徑的。這就會致使圖片引入失敗。這個問題是用file-loader解決的,file-loader能夠解析項目中的url引入(不只限於css),根據咱們的配置,將圖片拷貝到相應的路徑,再根據咱們的配置,修改打包後文件引用路徑,使之指向正確的文件。
簡易,對於比較小的圖片,使用base64編碼,能夠減小一次圖片的網絡請求;那麼對於比較大的圖片,使用base64就不適合了,編碼會和html混在一塊兒,一方面可讀性差,另外一方面加大了html頁面的大小,反而加大了下載頁面的大小,得不償失了呢,所以設置一個合理的limit是很是有必要的。

html-webpack-plugin插件的使用

下載模塊

npm i html-webpack-plugin --save-devgit

webpack.config.js文件配置
const path = require('path');
//2.導入模塊
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // 入口
    entry:{
        // 能夠有多個入口,也能夠有一個,若是一個,就默認從這一個入口開始分析
         "main" : './src/main.js'
    },
    output:{
        // 指定產出的目錄
        path: path.resolve('./dist'), //相對轉絕對
        filename:'build.js'
    },
    // 聲明模塊
    // 包含各個loader
    module:{
        loaders:[
            {   
                // 遇到後綴爲.css的文件,webpack先用css-loader加載器去解析這個文件
                // 最後計算完的css,將會使用style-loader生成一個內容爲最終解析完的css代碼的style標籤,放到head標籤裏。
                // webpack在打包過程當中,遇到後綴爲css的文件,就會使用style-loader和css-loader去加載這個文件。
                test:/\.css$/,
                loader:'style-loader!css-loader'
            },
            {
                test:/\.(jpg|png|jpeg|gif|svg)$/,
                loader:'url-loader?limit=100000'
            },
            {
                test:/\.less$/,
                loader:'style-loader!css-loader!less-loader'
            }
        ]
    },
    watch:true, //文件監視改動 自動產生build.js
    //添加插件 
    plugins:[
        new HtmlWebpackPlugin({
            //插件的執行運行與元素索引有關
            templat:'./src/index.html', //參照物
        })
    ]
}

CommonsChunkPlugin的使用

CommonsChunkPlugin主要是用來提取第三方庫和公共模塊,避免首屏加載的bundle文件或者按需加載的bundle文件體積過大,從而致使加載時間過長,着實是優化的一把利器.

chunk的分類
  • webpack當中配置的入口文件(entry)是chunk,能夠理解爲entry chunk
  • 入口文件以及它的依賴文件經過code splite(代碼分割) 出來的也是chunk,能夠理解爲children chunk
  • 經過CommonsChunkPlugin建立出來的文件也是chunk,能夠理解爲commons chunk
CommonsChunkPlugin可配置的屬性
  • name:能夠是已經存在的chunk(通常指入口文件)對應的name,那麼就會把公共模塊代碼合併到這個chunk上;不然,會建立名字爲name的commons chunk進行合併
  • filename:指定commons chunk的文件名
  • chunks:指定source chunk,即指定從哪些chunk當中去找公共模塊,省略該選項的時候,默認就是entry chunks
  • minChunks:既能夠是數字,也能夠是函數,還能夠是Infinity,具體用法和區別下面會說
驗證三種狀況
  • 不分離出第三方庫和自定義公共模塊
  • 分離出第三方庫、自定義公共模塊、webpack運行文件,但它們在同一個文件中
  • 單獨分離第三方庫、自定義公共模塊、webpack運行文件,各自在不一樣文件
不分離出第三方庫和自定義公共模塊

src目錄下各個文件內容,儘可能保持簡單,讓你們理解:

--common.js
    export const common = 'common file';
--main1.js
    import {common} from './common.js'
    import Vue from 'vue'
    console.log(Vue,`main1 ${common}`);
--main2.js
    import {common} from './common.js'
    import Vue from 'vue'
    console.log(Vue,`main1 ${common}`)

webpack.config.js

const path  = require('path');
module.exports = {
    // 入口
    entry:{
        // 能夠有多個入口,也能夠有一個,若是有一個就默認從這一個入口開始分析
        "main1":'./src/main1.js',
        "main2":'./src/main2.js'
    },
    output:{
        path:path.resolve('./dist'),//相對轉絕對
        filename:'[name].js'
    },
    watch:true,//文件監視改動 自動產出build.js
}

執行命令npm run build,

問題:查看main1.js和main2.js,會發現共同引用的common.js文件和vue都被打包進去了,這確定不合理,公共模塊重複打包,體積過大。

分離出第三方庫、自定義公共模塊、webpack運行文件

修改webpack.config.js新增一個入口文件vendor和CommonsChunkPlugin插件進行公共模塊的提取:

const path = require('path');
const webpack = require('webpack');
const packagejson = require('./package.json');
module.exports = {
    // 入口
    entry: {
        "main1": './src/main1.js',
        "main2": './src/main2.js',
        "vendor": Object.keys(packagejson.dependencies) //獲取生產環境依賴的庫
    },
    //出口
    output: {
        path: path.resolve('./dist'), //相對轉絕對
        filename: '[name].js'
    },
    watch: true, //文件監視改動 自動產出build.js
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['vendor'],
            filename: '[name].js'
        })
    ]
}

查看dist目錄,新增了一個vendor.js的文件

打包信息:

image-20180924224013776

經過查看vendor.js文件,發現main1.js和main2.js文件中依賴的vue和common.js都被打包進vendor.js中,同時還有webpack的運行文件。總的來講,咱們初步的目的達到,提取公共模塊,可是它們都在同一個文件中。

到這裏,確定有人但願自家的vendor.js純白無瑕,只包含第三方庫,不包含自定義的公共模塊和webpack運行文件,又或者但願包含第三方庫和公共模塊,不包含webpack運行文件。

其實,這種想法是對,特別是分離出webpack運行文件,由於每次打包webpack運行文件都會變,若是你不分離出webpack運行文件,每次打包生成vendor.js對應的哈希值都會變化,致使vendor.js改變,但實際上你的第三方庫實際上是沒有變,然而瀏覽器會認爲你原來緩存的vendor.js就失效,要從新去服務器中獲取,其實只是webpack運行文件變化而已,就要人家從新加載,好冤啊~

單獨分離出第三方庫、自定義公共模塊、webpack運行文件

這裏咱們分兩步走:

  1. 先單獨抽離出webpack運行文件
  2. 接着單獨抽離第三方庫和自定義公共模塊

(1)抽離webpack的運行文件

修改webpack配置文件

plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['vendor', 'runtime'],
            filename: '[name].js',
        })

其實上面這段代碼,等價於下面這段:

plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            filename: '[name].js'
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'runtime',
            filename: '[name].js',
            chunks: ['vendor']
        }),
    ]

上面兩段抽離webpack運行文件代碼的意思是建立一個名爲runtime的commons chunk進行webpack運行文件的抽離,其中source chunks是vendor.js。

查看dist目錄下,新增了一個runtime.js的文件,其實就是webpack的運行文件

再來查看一下命令行中webpack的打包信息,你會發現vendor.js的體積已經減少,說明已經把webpack運行文件提取出來了:

image-20180924224404680

但是,vendor.js中還有自定義的公共模塊common.js,人家只想vendor.js擁有項目依賴的第三方庫而已(這裏是jquery),這個時候把minChunks這個屬性引進來。

minChunks能夠設置爲數字、函數和Infinity,默認值是2,並非官方文檔說的入口文件的數量,下面解釋下minChunks含義:

  • 數字:模塊被多少個chunk公共引用才被抽取出來成爲commons chunk
  • 函數:接受 (module, count) 兩個參數,返回一個布爾值,你能夠在函數內進行你規定好的邏輯來決定某個模塊是否提取成爲commons chunk
  • Infinity:只有當入口文件(entry chunks) >= 3 才生效,用來在第三方庫中分離自定義的公共模塊

(2) 抽離第三方庫和自定義公共模塊

minChunks設爲Infinity,修改webpack配置文件以下

plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: ['vendor','runtime'],
            filename: '[name].js',
            minChunks: Infinity
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common',
            filename: '[name].js',
            chunks: ['main1','main2']//從first.js和second.js中抽取commons chunk
        }),
    ]

查看dist目錄下,新增了一個common.js的文件:

再來查看一下命令行中webpack的打包信息,自定義的公共模塊分離出來:

image-20180924225428549

這時候的vendor.js就純白無瑕,只包含第三方庫文件,common.js就是自定義的公共模塊,runtime.js就是webpack的運行文件。

webpack異步加載的原理

webpack ensure 有人稱它爲異步加載,也有人說作代碼切割。其實說白了,它就是把js模塊給獨立導出一個.js文件的,而後使用這個 模塊的時候,webpack會構造script dom元素,由瀏覽器發起異步請求這個js文件。

webpack.ensure的原理:

它就是 把一些js模塊給獨立出一個個js文件,而後須要用到的時候,在建立一個script對象,加入 到document.head對象中便可,瀏覽器會自動幫咱們發起請求,去請求這個js文件,在寫個回調,去 定義獲得這個js文件後,須要作什麼業務邏輯操做。

main.js依賴三個js

  • A.js是封裝aBtn按鈕點擊後,才執行的業務邏輯
  • B.js是封裝bBtn按鈕點擊後,才執行的業務邏輯
  • vue.js是封裝了main.js須要利用的包

針對上面的需求,優化方案

假設 A.js B.js vue.js都是很是大的文件 由於 A.js B.js 都不是main.js必須有的,即將來可能發生的操做,那麼咱們把 他們利用異步加載,當發生的時候再去加載就好了

vue.js.js是main.js當即立刻依賴的工具箱。可是它又很是的大,因此將其配置打包成一個公共模塊, 利用瀏覽器的併發加載,加快下載速度。ok,構思完成,開始實現。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <div id="app"></div>
    <button id="aBtn">Abtn</button>
    <br>
    <button id="bBtn">Bbtn</button>
    
</body>
</html>

定義了兩個button

而後看看 main.js

import Vue from 'vue'
console.log(Vue);
document.getElementById('aBtn').onclick = function(){
    require.ensure(['./B.js'],function(){
        var A = require('./A.js');
        alert(A.data);
        //異步裏面再導入同步模塊--實際是使用同步中的模塊
        var Vue1 = require('vue');
    })
}
document.getElementById('bBtn').onclick = function(){
    require.ensure([],function(){

        var B = require('./B.js');
        alert(B.data);

    })
}

能夠看到,A.js, B.js 都是點擊後才ensure進來的。何時加載完成呢? 就是 require.ensure() 第二個函數參數,即回調函數,它表示當下載js完成後,發生的。

webpack打包後,造成

image-20180925200630629

webpack-dev-server

下載模塊

1.npm install webpack-dev-server --save-dev

經常使用配置參數

--open 自動打開瀏覽器

--hot 熱更新 ,不在刷新的狀況下替換 css樣式

--inline 自動刷新

--port 9999 指定端口

--process 顯示編譯進度

在package.json文件中配置

image-20180920230626538

直接執行 npm run dev

es6的解析

模塊介紹

babel-core:

javascript babel-core的做用是把js代碼分析成ast(抽象語法樹),方便各個插件分析語法進行相應的處理。有些新語法在低版本 js 中是不存在的,如箭頭函數,rest 參數,函數默認值等,這種語言層面的不兼容只能經過將代碼轉爲 ast,分析其語法後再轉爲低版本 js

abel轉譯器自己,提供了babel的轉譯API,如babel.transform等,用於對代碼進行轉譯。像webpack的babel-loader就是調用這些API來完成轉譯過程的。

babel-loader:

在將es6的代碼transform進行轉義,就是經過babel-loader來完成

babel-preset-env

若是要自行配置轉譯過程當中使用的各種插件,那太痛苦了,因此babel官方幫咱們作了一些預設的插件集,稱之爲preset,這樣咱們只須要使用對應的preset就能夠了。以JS標準爲例,babel提供了以下的一些preset:

  • es2015
  • es2016
  • es2017
  • env
    es20xx的preset只轉譯該年份批准的標準,而env則代指最新的標準,包括了latest和es20xx各年份
    另外,還有 stage-0到stage-4的標準成形以前的各個階段,這些都是實驗版的preset,建議不要使用。

babel-plugin-transform-runtime

Babel 默認只轉換新的 JavaScript 語法,而不轉換新的 API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(好比 Object.assign)都不會轉譯。若是想使用這些新的對象和方法,必須使用 babel-polyfill,爲當前環境提供一個墊片。

參考連接:https://segmentfault.com/q/1010000005596587?from=singlemessage&isappinstalled=1 看這個回答,說的很是詳細。

安裝模塊

npm install babel-core babel-loader babel-preset-env babel-plugin-transform-runtime -D

在webpack-dev-config.js配置
loader:[
    {
        // 處理es6,7,8
        test:/\.js$/,
        loader:'babel-loader',
        options:{
            presets:['env'],//處理關鍵字
            plugins:['transform-runtime'],//處理函數
        }
    }
]

配置完成以後執行 npm run dev

發現!!!!!

image-20180920013826881

解決:

排除不包含node_modules的路徑,而後再配置文件中修改

loader:[
    {
        // 處理es6,7,8
        test:/\.js$/,
        loader:'babel-loader',
         exclude:/node_modules/,
        options:{
            presets:['env'],//處理關鍵字
            plugins:['transform-runtime'],//處理函數
        }
    }
]

也會發現,當排除掉node_modules文件中的es6代碼編譯後,編譯的時間也快了
之前出錯的,3601毫秒的時候就開始出錯了。。。。

image-20180920013905622

排除掉node_modules以後

image-20180920013922930

單文件引入

下載包

npm install vue-loader@14.1.1 vue-template-compiler@2.5.17 -D

建立App.vue文件
//組件的模板結構
<template>
    <div>
        {{ text }}
    </div>
</template>

//組件的業務邏輯
<script>
export default {
    data(){
        return {
            text:'hello Single file'                
        }
    }
}
</script>
//組件的樣式
<style>
    body{
        background-color: green;
    }
</style>
建立入口文件main.js
import Vue from 'vue';
import App from './App'
new Vue({
    el:'#app',
    //Render函數是Vue2.x版本新增的一個函數;
    // 使用虛擬dom來渲染節點提高性能,由於它是基於JavaScript計算。
    // 經過使用createElement(h)來建立dom節點。createElement是render的核心方法。其Vue編譯的時候會把template裏面的節點解析成虛擬dom;
    render:c=>c(App)
    // components:{
    //      App
    // },
    // template:`<App />`
});
webpack.dev.config.js文件配置
// 處理Vue文件
{
    test:/\.vue$/,
    loader:'vue-loader'
}

vue-cli2.x腳手架的使用

參考連接:https://github.com/vuejs/vue-cli/tree/v2#vue-cli--

安裝:

npm install -g vue-cli

用法:

$ vue init < template-name >  < project-name >

例:

$ vue init webpack my-project

目前可用的模塊包括:

  • webpack - 一個功能齊全的Webpack + vue-loader設置,具備熱重載,linting,測試和css提取功能。
  • webpack-simple - 一個簡單的Webpack + vue-loader設置,用於快速原型設計。
  • browserify -全功能Browserify + vueify設置用熱重裝載,linting&單元測試。
  • browserify -simple - 一個簡單的Browserify + vueify設置,用於快速原型設計。
  • pwa - 基於webpack模板的vue-cli的PWA模板
  • simple - 單個HTML文件中最簡單的Vue設置

vue-cli3x腳手架的使用

vue-cli3x的官方文檔:https://cli.vuejs.org/

Vue-cli3 中vue.config.js文件配置參考文檔:https://cli.vuejs.org/zh/config/#integrity

// vue.config.js 配置說明
//官方vue.config.js 參考文檔 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 這裏只列一部分,具體配置參考文檔
module.exports = {
  // 部署生產環境和開發環境下的URL。
  // 默認狀況下,Vue CLI 會假設你的應用是被部署在一個域名的根路徑上
  //例如 https://www.my-app.com/。若是應用被部署在一個子路徑上,你就須要用這個選項指定這個子路徑。例如,若是你的應用被部署在 https://www.my-app.com/my-app/,則設置 baseUrl 爲 /my-app/。
  baseUrl: process.env.NODE_ENV === "production" ? "./" : "/",
 
  // outputDir: 在npm run build 或 yarn build 時 ,生成文件的目錄名稱(要和baseUrl的生產環境路徑一致)
  outputDir: "dist",
  //用於放置生成的靜態資源 (js、css、img、fonts) 的;(項目打包以後,靜態資源會放在這個文件夾下)
  assetsDir: "assets",
  //指定生成的 index.html 的輸出路徑  (打包以後,改變系統默認的index.html的文件名)
  // indexPath: "myIndex.html",
  //默認狀況下,生成的靜態資源在它們的文件名中包含了 hash 以便更好的控制緩存。你能夠經過將這個選項設爲 false 來關閉文件名哈希。(false的時候就是讓原來的文件名不改變)
  filenameHashing: false,
 
  //   lintOnSave:{ type:Boolean default:true } 問你是否使用eslint
  lintOnSave: true,
  //若是你想要在生產構建時禁用 eslint-loader,你能夠用以下配置
  // lintOnSave: process.env.NODE_ENV !== 'production',
 
  //是否使用包含運行時編譯器的 Vue 構建版本。設置爲 true 後你就能夠在 Vue 組件中使用 template 選項了,可是這會讓你的應用額外增長 10kb 左右。(默認false)
  // runtimeCompiler: false,
 
  /**
   * 若是你不須要生產環境的 source map,能夠將其設置爲 false 以加速生產環境構建。
   *  打包以後發現map文件過大,項目文件體積很大,設置爲false就能夠不輸出map文件
   *  map文件的做用在於:項目打包後,代碼都是通過壓縮加密的,若是運行時報錯,輸出的錯誤信息沒法準確得知是哪裏的代碼報錯。
   *  有了map就能夠像未加密的代碼同樣,準確的輸出是哪一行哪一列有錯。
   * */
  productionSourceMap: false,
 
  // 它支持webPack-dev-server的全部選項
  devServer: {
    host: "localhost",
    port: 1111, // 端口號
    https: false, // https:{type:Boolean}
    open: true, //配置自動啓動瀏覽器
    // proxy: 'http://localhost:4000' // 配置跨域處理,只有一個代理
 
    // 配置多個代理
    proxy: {
      "/api": {
        target: "<url>",
        ws: true,
        changeOrigin: true
      },
      "/foo": {
        target: "<other_url>"
      }
    }
  }
};

RESTful

先後端分離:

​ 後端提供接口(api)

​ 前端寫頁面 ajax技術

40張表 增刪改查 4接口

​ http://127.0.0.1:8080/user

​ http://127.0.0.1:8080/add_user

http://127.0.0.1:8080/delete_user

http://127.0.0.1:8080/update_user

(1)分工明確,提升效率 ,兼容問題

RESTful 規範

  一種軟件的架構風格,設計風格,而不是標準,爲客戶端和服務端的交互提供一組設計原則和約束條件。

一 面向資源編程

  每一個URL表明一種資源,URL中儘可能不要用動詞,要用名詞,每每名詞跟數據庫表格相對應。

​ 通常來講,數據庫中的表都是同種記錄的集合,全部API中的名詞也應該使用複數。

​ 舉例來講,有一個API提供動物園(zoo)的信息,還包括各類動物和僱員的信息,則它的路徑應該設計成下

面這樣。

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
二 HTTP動詞

​ 對於資源的具體操做類型,由HTTP動詞表示

​ 經常使用的HTTP動詞有下面五個(括號裏對應的sql命令)

GET(SELECT):從服務器取出資源(一項或多項)。
POST(CREATE):在服務器新建一個資源。
PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源)。
PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從服務器刪除資源。

  

三 在URL中體現版本
https://www.bootcss.com/v1/

  https://v1.bootcss.com/

四 在URL中體現是不是API

  https://www.bootcss.com/api/mycss

  https://api.bootcss.com/mycss

五 在URL中的過濾條件

​ 若是記錄數量不少,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果。

?limit=10:指定返回記錄的數量
?offset=10:指定返回記錄的開始位置。
?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
?sortby=name&order=asc:指定返回結果按照哪一個屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件

select post,count(1) from user where id > 20 group by post having avg(age) > 25 order by age desc limit 0,3;

六 儘可能使用HTTPS

  https://www.bootcss.com/v1/mycss

七 響應時設置狀態碼

  1** 信息,服務器收到請求,須要請求者繼續執行操做

  2** 成功,操做被成功接收並處理

  3** 重定向,須要進一步的操做以完成請求

  4** 客戶端錯誤,請求包含語法錯誤或沒法完成請求

  5** 服務器錯誤,服務器在處理請求的過程當中發生了錯誤

八 返回值

  GET請求 返回查到全部或單條數據

  POST請求 返回新增的數據

  PUT請求 返回更新數據

  PATCH請求 局部更新 返回更新整條數據

  DELETE請求 返回值爲空

九 返回錯誤信息

若是狀態碼是4xx,就應該向用戶返回出錯信息。通常來講,返回的信息中將error做爲鍵名,出錯信息做爲鍵值便可。

{
    error: "Invalid API key"
}
十 Hypermedia API

  若是遇到須要跳轉的狀況 攜帶調轉接口的URL

 Hypermedi API的設計,好比github的API就是這種設計,訪問api.github.com會獲得一個全部可用的API的網址列表。

{
  "current_user_url": "https://api.github.com/user",
  "authorizations_url": "https://api.github.com/authorizations",
  // ...
}

從上面能夠看到,若是想獲取當前用戶的信息,應該去訪問 api.github.com/user,就會獲得下面的記過

{
message: "Requires authentication",
documentation_url: "https://developer.github.com/v3/users/#get-the-authenticated-user"
}
十一 其餘

(1)API的身份認證應該使用OAuth 2.0框架

(2)服務器返回的數據格式,應該儘可能使用JSON,避免使用XML

相關文章
相關標籤/搜索