搭建基于webpack的vue項目

簡單搭建基于webpack環境下的Vue項目,在此過程中熟悉webpack以及vue的簡單用法,按照步驟一步一步進行,從依賴包安裝到webpack配置到vue單文件組件的引用到最后打包發布。

第一步:安裝webpack

首先自行選擇路徑創建項目
并新建一個文件夾 webpack-vue
全局安裝webpack,安裝之前先檢查全局是否已經安裝并且確定版本

如果沒有安裝請自行安裝,命令如下:

yarn add webpack webpack-cli -g

檢查版本命令為:

F:\vue-learns\webpack-vue>webpack -v
4.23.0

F:\vue-learns\webpack-vue>webpack-cli -v
3.1.2

第二步:項目初始化

進入項目目錄:

cd vue-learns
cd webpack-vue

yarn init -y
//新建package.json
//和npm功能類似,如果還沒安裝yarn,網上有大量教程在此不贅述

安裝vue webpack webpack-dev-server

yarn add vue (--save可省略)
yarn add webpack webpack-dev-server --dev
//--save 的意思是將模塊安裝到項目目錄下,并在package文件的dependencies節點寫入依賴。
//--dev 的意思是將模塊安裝到項目目錄下,并在package文件的devDependencies節點寫入依賴。

在項目根目錄下新建index.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

在項目根目錄下新建webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {};

新建src文件夾目錄,并且在src下新建main.js

webpack的思想就是一切皆模塊,官方推薦使用commonJS規范,這使得我們瀏覽器端也可以使用commonJS的模塊化寫法 :module.exports = {}

src目錄下新建一個utils.js

module.exports = function say() {
    console.log('hello world');
}

main.js :

var say = require('./utils');
say();

webpack.config.js:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './src/main.js', // 項目的入口文件,webpack會從main.js開始,把所有依賴的js都加載打包
  output: {
    path: path.resolve(__dirname, './dist'), // 項目的打包文件路徑
    publicPath: '/dist/', // 通過devServer訪問路徑
    filename: 'build.js' // 打包后的文件名
  },
  devServer: {
    historyApiFallback: true, //historyApiFallback設置為true那么所有的路徑都執行index.html。
    overlay: true // 將錯誤顯示在html之上
  }
};

webpack4.0 可能會運行報錯,需要重新安裝 yarn add -D webpack-cli

yarn run dev

可以發現瀏覽器自動打開一個http://localhost:8080/ 的頁面 F12打開控制臺可以看到有hello world打出
隨意修改utils.js,可以發現瀏覽器會自動刷新

如果我們希望看打包后的bundle.js文件,運行

yarn run build

第三步:引入vue

main.js:

import Vue from 'vue';

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
});

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        {{message}}
    </div>
    <script src="/dist/build.js"></script>
    
</body>

</html>

webpack.config.js :

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'build.js'
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    }
};

重新運行npm run dev,可以看到,清一下緩存(ctrl+shift+delete),頁面正常顯示了'Hello Vue!'

第四步:引入scss和css

webpack默認只支持js的模塊化,如果需要把其他文件也當成模塊引入,就需要相對應的loader解析器

yarn add node-sass css-loader vue-style-loader sass-loader --dev

webpack.config.js:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'build.js'
    },
    devServer: {
        historyApiFallback: true,
        overlay: true
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    module: {
        rules: [
            { //匹配后綴名為css的文件,然后分別用css-loader,vue-style-loader去解析
              //解析器的執行順序是從下往上(先css-loader再vue-style-loader)
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'css-loader'
                ],
            },
            {
                test: /\.scss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader'
                ],
            },
            {
                test: /\.sass$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    'sass-loader?indentedSyntax'
                ],
            }
        ]
    }
};

因為我們這里用vue開發,所以使用vue-style-loader,其他情況使用style-loader
css-loader使得我們可以用模塊化的寫法引入css,vue-style-loader會將引入的css插入到html頁面里的style標簽里

我們現在在src目錄下新建style目錄,style目錄里新建common.scss
common.scss:

body {
  background: #fed;
}

main.js:

import './style/common.scss';

第五步 : 使用babel轉碼

ES6的語法大多數瀏覽器依舊不支持,bable可以把ES6轉碼成ES5語法,這樣我們就可以大膽的在項目中使用最新特性了

yarn add babel-core babel-loader babel-preset-env babel-preset-stage-3 --dev

在項目根目錄新建一個.babelrc文件

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

webpack.config.js添加一個loader

{
    test: /\.js$/,
    loader: 'babel-loader',
    exclude: /node_modules/  
}
//exclude表示忽略node_modules文件夾下的文件,不用轉碼

現在我們來試下async await語法吧
utils.js

export default function getData() {
    return new Promise((resolve, reject) => {
        resolve('ok');
    })
}

main.js

import getData from './utils';
import Vue from 'vue';

import './style/common.scss';

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  },
  methods: {
    async fetchData() {
      const data = await getData();
      this.message = data;
    }
  },
  created() {
    this.fetchData();
  }
});

第六步 : 引入圖片資源

把圖片也當成模塊引入

yarn add file-loader --dev

webpack.config.js添加一個loader

{
    test: /\.(png|jpg|gif|svg)$/,
    loader: 'file-loader',
    options: {
        name: '[name].[ext]?[hash]'
    }
}

在src目錄下新建一個img目錄,存放一張圖片logo.png

main.js:

import getData from './utils';
import Vue from 'vue';

import './style/common.scss';


Vue.component('my-component', {
  template: '<img :src="url" />',
  data() {
    return {
      url: require('./img/logo.png')
    }
  }
})

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue !'
  },
  methods: {
    async fetchData() {
      const data = await getData();
      this.message = data;
    }
  },
  created() {
    this.fetchData()
  }
});

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
<div id="app">
    {{message}}
    <my-component/>
</div>
<script src="/dist/build.js"></script>

</body>

</html>

第七步:單文件組件

在前面的例子里,我們使用 Vue.component 來定義全局組件
在實際項目里,更推薦使用單文件組件

yarn add vue-loader vue-template-compiler --dev

添加一個loader:

{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        loaders: {
            'scss': [
                'vue-style-loader',
                'css-loader',
                'sass-loader'
            ],
            'sass': [
                'vue-style-loader',
                'css-loader',
                'sass-loader?indentedSyntax'
            ]
        }
    }
}

在src目錄下新建一個App.vue

<template>
    <div id="app">
        <h1>{{ msg }}</h1>
        <img src="./img/logo.png">
        <input type="text" v-model="msg">
    </div>
</template>

<script>

  import getData from './utils';

  export default {
    name: 'app',
    data () {
      return {
        msg: 'Welcome to Your Vue.js'
      }
    },
    created() {
      this.fetchData();
    },
    methods: {
      async fetchData() {
        const data = await getData();
        this.msg = data;
      }
    }
  }
</script>

<style lang="scss">
    #app {
        font-family: "Avenir", Helvetica, Arial, sans-serif;

        h1 {
            color: #CC3333;
        }
    }
</style>

main.js:

import Vue from 'vue';
import App from './App.vue';

import './style/common.scss';

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app"></div>
    <script src="/dist/build.js"></script>
</body>

</html>

最后,打包發布

run build
在package.json中的script中 進行壓縮

var path = require('path');
var webpack = require('webpack');

module.exports = {
    // 省略...
    optimization: {
        splitChunks: {
         chunks: 'all'
         }
     }
  }

至此,一個簡單的vue開發環境搭建完成。

搭建基于webpack4.0的vue項目,這篇文章就夠了
從零開始搭建一個簡單的基于webpack的vue開發環境

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容