webpack4+加vue2+從零開(kāi)始搭設(shè)vue項(xiàng)目

@TOC

本地環(huán)境

node -v // v9.1.0
npm -v // 6.5.0
webpack -v // 4.32.2
webpack-cli -v // 3.3.2

這里需要注意的是webpack4+以后需要單獨(dú)安裝webpack-cli

起步

1.初始化項(xiàng)目

npm init 

一直enter生成package.json文件(小技巧:npm init -y 可以免去繁瑣的enter)

2.安裝依賴

npm i webpack webpack-cli webpack-dev-server --save-dev

想要深入上述依賴請(qǐng)轉(zhuǎn)webpack文檔

依賴安裝成功接下來(lái)就開(kāi)始動(dòng)手吧

3.目錄文件配置

根目錄鼠標(biāo)右鍵新建index.html webpack.config.js src文件夾或:

// window
type >webpcak.config.js 
type >index.html 
md src

//mac 土豪玩家
touch webpcak.config.js 
touch index.html
mkdir src

src目錄下面新建 main.js

此時(shí)目錄如下

project/
        src/
            main.js
        webpack.config.js
        index.html
        package.json

內(nèi)容如下:

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack從零搭設(shè)</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

// webpack.config.js
const path = require('path');
const webpack = require('webpack');
modul.exports = {}

4.配置index.html及webpack.config.js

首先
main.js修改如下:

// src/main.js
console.log('hello world');

webpack.config.js修改如下:

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {  // module.exports commonjs規(guī)范
  entry: './src/main.js', // 項(xiàng)目入口文件暇赤,webpack將從main.js開(kāi)始,把所有依賴的js都打包
  output: {
    path: path.resolve(__dirname, './dist'), // 項(xiàng)目的打包后的輸出路徑 可修改
    publicPath: '/dist/', // 通過(guò)devServer訪問(wèn)路徑 可修改
    filename: 'build.js' // 打包后的文件名 可修改
  },
  devServer: {
    historyApiFallback: true, // When using the HTML5 History API, the `index.html` page will likely have to be served in place of any `404` responses
    overlay: true //Shows a full-screen overlay in the browser when there are compiler errors or warnings. Disabled by default. If you want to show only compiler errors
  },
};

webpack配置里的核心:

  • entry: webpack打包的入口(不是代碼執(zhí)行入口)重抖;
  • output: webpack打包后生成的靜態(tài)資源文件棒妨,最終會(huì)被html引用踪古;
  • loader: 轉(zhuǎn)化非js文件成webpack能夠處理的js文件;對(duì)js文件進(jìn)行加工券腔;
  • plugins: 顧名思義---webpack打包過(guò)程中輔助插件伏穆;

index.html 修改如下 增加引入打包后的js

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack從零搭設(shè)</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="/dist/build.js"></script>
</html>

package.json修改如下:

"scripts": {
    "dev": "webpack-dev-server --open --hot",
    "build": "webpack --progress --hide-modules"
  },

webpack-dev-server會(huì)啟動(dòng)一個(gè)靜態(tài)資源web服務(wù)器 --hot參數(shù)表示啟動(dòng)熱更新

重新啟動(dòng)服務(wù)

npm run dev

打開(kāi)控制臺(tái)可以看到 有輸出hello world


控制臺(tái)輸出hello world

5.vue的起步

安裝vue

npm install vue --save

修改main.js如下

// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js'  // 解決You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build

// console.log('hello world');

var app = new Vue({
  el: '#app',
  data: {
    mess: 'Hello Vue@2.0!'
  }
})

此時(shí) 修改index.html如下:

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>webpack從零搭設(shè)</title>
</head>
<body>
<div id="app">
    {{ mess }}
</div>
</body>
<script src="/dist/build.js"></script>
</html>

重新啟動(dòng)服務(wù)

npm run build
npm run dev

此時(shí)


控制臺(tái)報(bào)錯(cuò),頁(yè)面也未顯示hello Vue纷纫!

查閱資料發(fā)現(xiàn):
vue有兩種形式的代碼 compiler(模板)模式和runtime模式(運(yùn)行)
vue模塊的package.json的main字段默認(rèn)為runtime模式枕扫, 指向"dist/vue.runtime.common.js"位置。這是vue升級(jí)到2.0之后就有的特點(diǎn)涛酗。

但此時(shí)我們main.js的寫法是

// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js'  // 解決You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build

// console.log('hello world');

var app = new Vue({
  el: '#app',
  data: {
    mess: 'Hello Vue@2.0!'
  }
})

解決方案 一
// src/main.js
//import Vue from 'vue';
 import Vue from 'vue/dist/vue.esm.js'  // 解決You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build

// console.log('hello world');

var app = new Vue({
  el: '#app',
  data: {
    mess: 'Hello Vue@2.0!'
  }
})

因?yàn)関ue2.0默認(rèn)的是runtime模式铡原,需要借助如 webpack 的 vue-loader 工具把 .vue 文件編譯成 JavaScript代碼;

解決方案 二(常規(guī)操作)
// webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {  //module.exports commonjs規(guī)范
  entry: './src/main.js', // 項(xiàng)目的入口文件商叹,webpack會(huì)從main.js開(kāi)始燕刻,把所有依賴的js都加載打包
  output: {
    path: path.resolve(__dirname, './dist'), // 項(xiàng)目的打包文件路徑
    publicPath: '/dist/', // 通過(guò)devServer訪問(wèn)路徑
    filename: 'build.js' // 打包后的文件名
  },
  devServer: {
    historyApiFallback: true,
    overlay: true
  },
  resolve: { // 修改別名,import Vue from ‘vue’ 這行代碼被解析為 import Vue from ‘vue/dist/vue.esm.js
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
};

這個(gè)修改和上次是一樣的意思剖笙,不過(guò)相對(duì)雅觀很多...

解決方案 三

修改main.js的模式

  1. compiler 模式
// src/main.js
// compiler 模式
new Vue({
  el: '#app',
})

2.runtime 模式

//runtime模式
new Vue({
render: h => h(App)  // App.vue
}).$mount("#app")

將1換成2卵洗,但我們推薦使用方案二;

最后 頁(yè)面展示如下:


hello Vue@2.0

引入css和scss

webpack默認(rèn)支持的是js的模塊化,如果需要其他類型文件也支持模塊化開(kāi)發(fā)过蹂,則需要引入相應(yīng)的loader用以解析!

安裝相關(guān)依賴

npm i node-sass css-loader vue-style-loader sass-loader --save-dev

webpack.config.js 修改如下

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {  //module.exports commonjs規(guī)范
  entry: './src/main.js', // 項(xiàng)目的入口文件十绑,webpack會(huì)從main.js開(kāi)始,把所有依賴的js都加載打包
  output: {
    path: path.resolve(__dirname, './dist'), // 項(xiàng)目的打包文件路徑
    publicPath: '/dist/', // 通過(guò)devServer訪問(wèn)路徑
    filename: 'build.js' // 打包后的文件名
  },
  devServer: {
    historyApiFallback: true,
    overlay: true
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
   module: {
     rules: [
       {
         test: /\.css$/,
         use: [
           'vue-style-loader',
           'css-loader'
         ],
       },
       { // scss
         test: /\.scss$/,
         use: [
           'vue-style-loader',
           'css-loader',
           'sass-loader'
         ],
       }
     ]
   }
};

此時(shí)scss 及 css都能在開(kāi)發(fā)中使用并且模塊化引入了

語(yǔ)法轉(zhuǎn)譯 ES6 => ES5

引入相關(guān)依賴 利用bable轉(zhuǎn)譯

npm i babel-core babel-loader babel-preset-env babel-preset-stage-3 --save-dev

其中 babel-preset-stage是不同階段語(yǔ)法提案的轉(zhuǎn)碼規(guī)則(共有4個(gè)階段)酷勺,選裝一個(gè),其中0最厲害

npm install --save-dev babel-preset-stage-0
npm install --save-dev babel-preset-stage-1
npm install --save-dev babel-preset-stage-2
npm install --save-dev babel-preset-stage-3

// .babelrc
{
  "presets": [
    ["env", { "modules": false }],
    "stage-3"
  ]
}

同時(shí)修改 webpack.config.js

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {  //module.exports commonjs規(guī)范
  entry: './src/main.js', // 項(xiàng)目的入口文件本橙,webpack會(huì)從main.js開(kāi)始,把所有依賴的js都加載打包
  output: {
    path: path.resolve(__dirname, './dist'), // 項(xiàng)目的打包文件路徑
    publicPath: '/dist/', // 通過(guò)devServer訪問(wèn)路徑
    filename: 'build.js' // 打包后的文件名
  },
  devServer: {
    historyApiFallback: true,
    overlay: true
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
   module: {
     rules: [
       {
         test: /\.css$/,
         use: [
           'vue-style-loader',
           'css-loader'
         ],
       },
       { // scss
         test: /\.scss$/,
         use: [
           'vue-style-loader',
           'css-loader',
           'sass-loader'
         ],
       },
       { // 添加解析js的loader
         test: /\.js$/,
         loader: 'babel-loader',
         exclude: /node_modules/
       }
     ]
   }
};

此時(shí)我們修改main.js嘗試使用es6語(yǔ)法

// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js'  // 解決You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build


// console.log('hello world');

const say = function () {
  return new Promise((resolve, reject) => {
    resolve('I am es6');
  })
}


var app = new Vue({
  el: '#app',
  data: {
    mess: 'Hello Vue@2.0!'
  },
  methods: {
    updateData() {
      say().then((res)=>{
        this.mess = res;
      });
    },
    
  },
  created() {
    this.updateData();
  }
})

此時(shí)頁(yè)面輸出效果如下


I am es6

雖然滿足我們使用了脆诉,那么接下來(lái)我們嘗試一下ES7支持與否
main.js修改如下:

import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js'  // 解決You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build


// console.log('hello world');

const say = function () {
  return new Promise((resolve, reject) => {
    resolve('I am es7');
  })
}


var app = new Vue({
  el: '#app',
  data: {
    mess: 'Hello Vue@2.0!'
  },
  methods: {
    /*updateData() {
      say().then((res)=>{
        this.mess = res;
      });
    },*/
    async updateData() {
      const mess = await say();
      this.mess = mess;
    }
  },
  created() {
    this.updateData();
  }
})

頁(yè)面展示如下:


ES7測(cè)試

此時(shí)看到控制臺(tái)報(bào)錯(cuò)

"ReferenceError: regeneratorRuntime is not defined"

查閱相關(guān)文章發(fā)現(xiàn)甚亭, 要想對(duì)es7語(yǔ)法進(jìn)行支持,還需要安裝相關(guān)依賴進(jìn)行轉(zhuǎn)譯击胜;

這里有兩種方案
方案一
npm i --save-dev babel-plugin-transform-runtime

修改.babelrc文件

// .babelrc
{
    "presets": [
        ["env", { "modules": false }],
        "stage-3"
    ],
    "plugins": [[  //  參考 http://www.reibang.com/p/7a7f7abcddb5
        "transform-runtime",
        {
            "helpers": false,
            "polyfill": false,
            "regenerator": true,
            "moduleName": "babel-runtime"
        }
    ]]
}

這里順帶解釋一下preset與babel的關(guān)系:

  • preset中已經(jīng)包含了一組用來(lái)轉(zhuǎn)換ES6+的語(yǔ)法的插件,如果只使用少數(shù)新特性而非大多數(shù)新特性,可以不使用preset而只使用對(duì)應(yīng)的轉(zhuǎn)換插件
  • babel默認(rèn)只轉(zhuǎn)換語(yǔ)法,而不轉(zhuǎn)換新的API,如需使用新的API,還需要使用對(duì)應(yīng)的轉(zhuǎn)換插件或者polyfill

例如亏狰,默認(rèn)情況下babel可以將箭頭函數(shù),class等語(yǔ)法轉(zhuǎn)換為ES5兼容的形式偶摔,但是卻不能轉(zhuǎn)換Map暇唾,Set,Promise等新的全局對(duì)象辰斋,這時(shí)候就需要使用polyfill去模擬這些新特性

此時(shí)看到頁(yè)面輸出正常:


ES7正常
方案二

全局babel-polyfill

npm i babel-polyfill --save-dev

webpack.config.js修改如下 注意看注釋

// webpack.config.js
  // entry: './src/main.js', // 項(xiàng)目的入口文件策州,webpack會(huì)從main.js開(kāi)始,把所有依賴的js都加載打包
  entry: ['babel-polyfill', './src/main.js'], // 項(xiàng)目的入口文件亡呵,webpack會(huì)從main.js開(kāi)始抽活,把所有依賴的js都加載打包 參考 http://www.reibang.com/p/3b27dfc6785c

此時(shí)重新跑項(xiàng)目npm run dev 結(jié)果方案一

es6與es7轉(zhuǎn)譯部分參考文章
babel-polyfill的幾種使用方式
babel的使用

文章最后

項(xiàng)目搭建,缺啥補(bǔ)啥C淌病! 項(xiàng)目完整地址查看@王一諾wlove_c/webpack4.0+vue2.0

2019年6月16日文章更新webpack代理配置

此次更新的原因是在一個(gè)技術(shù)分享群有同學(xué)問(wèn)到\color{red}{webpack如何設(shè)置代理帶本地開(kāi)發(fā)項(xiàng)目}丁逝,當(dāng)時(shí)有點(diǎn)懵汁胆,webpack都更新到4.34.0了還有同學(xué)不會(huì)設(shè)置代理,所以借助這邊文章更新一下代理配置霜幼;

安裝依賴 webpack-dev-server

 npm install webpack-dev-server --save-dev

實(shí)際上webpack是通過(guò)http-proxy-middleware來(lái)作方向代理解決跨域的,詳情有興趣的同學(xué)可以自己了解一下

修改配置如下

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

module.exports = {  //module.exports commonjs規(guī)范
   ...

  devServer: {
    historyApiFallback: true,
    overlay: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 接口的域名和端口 如果端口為80則可以不寫
        pathRewrite: {'^/api' : ''}, // 如果不是以api開(kāi)頭的可以清空
        changeOrigin: true,     // target是域名的話嫩码,需要這個(gè)參數(shù),
        secure: false,          // 默認(rèn)情況下罪既,不接受運(yùn)行在 HTTPS 上铸题,且使用了無(wú)效證書的后端服務(wù)器。如果你想要接受琢感,修改配置如下:
        },
    },
  },

   ...
};

此時(shí)你跑項(xiàng)目的時(shí)候 npm run dev 時(shí) 你會(huì)發(fā)現(xiàn)丢间,請(qǐng)求到 /api/users 現(xiàn)在會(huì)被代理到請(qǐng)求 http://localhost:3000/api/users。并且不會(huì)有跨域問(wèn)題驹针!不過(guò)后端同學(xué)要允許跨域或者設(shè)置域名白名單喔

更多webpack-dev-server配置可以轉(zhuǎn)@webpack/devserver-proxy

如果你想要nginx作代理的話也是可以滴烘挫;詳情請(qǐng)轉(zhuǎn)我的另一篇文章@王一諾Eno的文章nginx部署/代理/跨域

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市柬甥,隨后出現(xiàn)的幾起案子饮六,更是在濱河造成了極大的恐慌其垄,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卤橄,死亡現(xiàn)場(chǎng)離奇詭異绿满,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)窟扑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門喇颁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人辜膝,你說(shuō)我怎么就攤上這事无牵。” “怎么了厂抖?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵茎毁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我忱辅,道長(zhǎng)七蜘,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任墙懂,我火速辦了婚禮橡卤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘损搬。我一直安慰自己碧库,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布巧勤。 她就那樣靜靜地躺著嵌灰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪颅悉。 梳的紋絲不亂的頭發(fā)上沽瞭,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音剩瓶,去河邊找鬼驹溃。 笑死,一個(gè)胖子當(dāng)著我的面吹牛延曙,可吹牛的內(nèi)容都是我干的豌鹤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼搂鲫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼傍药!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拐辽,失蹤者是張志新(化名)和其女友劉穎拣挪,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體俱诸,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡菠劝,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了睁搭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赶诊。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖园骆,靈堂內(nèi)的尸體忽然破棺而出舔痪,到底是詐尸還是另有隱情,我是刑警寧澤锌唾,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布锄码,位于F島的核電站,受9級(jí)特大地震影響晌涕,放射性物質(zhì)發(fā)生泄漏滋捶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一余黎、第九天 我趴在偏房一處隱蔽的房頂上張望重窟。 院中可真熱鬧,春花似錦惧财、人聲如沸巡扇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)霎迫。三九已至,卻和暖如春帘靡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓤帚。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工描姚, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戈次。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓轩勘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親怯邪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子绊寻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容