從零開始使用 Webpack 搭建 Vue 開發環境

建立項目

先建立一個空目錄,在該目錄打開命令行,執行 npm init 命令建立一個項目(沒法執行 npm 命令?須要先安裝 Node),這個過程會提示輸入一些內容,隨意輸入就行,完成後會自動生成一個 package.json 文件,裏面包含剛纔輸入的內容javascript

建立一個 index.html 頁面,因爲使用的是 Vue 開發單頁應用,因此一般一個 html 文件就夠了,內容也很簡單,就一個 div#appcss

projecthtml

project-name
+ |- index.html
  |- package.json

index.htmlvue

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>這是標題</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

projectjava

project-name
  |- index.html
+ |- index.js
  |- package.json
+ |- webpack.config.js

建立一個 index.js 做爲項目的主入口,建立一個 webpack.config.js 文件做爲 Webpack 的配置文件,內容以下node

webpack.config.jswebpack

'use strict'

const path = require('path')

module.exports = {
  mode: 'development',
  entry: './index.js',
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'dist')
  }
}

執行 npm install --save-dev webpack-cli 安裝 Webpackios

在 package.json 文件對應的 scripts 處寫入命令git

package.jsones6

{
    "scripts": {
+     "build": "webpack"
    }
  }

執行 npm run build 便可完成打包,打包成功後的文件放在 dist 目錄裏面(這是由配置文件自定義的),目前打包出來的只有一個 index.js 文件

啓動本地服務

使用 webpack-dev-server 來啓動本地服務,方便開發以及本地調試

執行 npm install --save-dev webpack webpack-dev-server

在 package.json 文件對應的 scripts 處寫入命令

package.json

{
    "scripts": {
+     "dev": "webpack-dev-server",
      "build": "webpack"
    }
  }

執行 npm run dev 便可啓動本地服務,訪問 localhost:8080 便可,8080 是默認的端口號,修改端口號配置以下

webpack.config.js

module.exports = {
  // ...
  devServer: {
    compress: true,
    port: 8080
  }
}

生成 HTML 文件

使用 html-webpack-plugin 來生成 HTML 文件

執行 npm install --save-dev html-webpack-plugin

在 webpack.config.js 配置文件中添加

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './index.html'
    })
  ]
}

安裝 Vue

執行 npm install --save-dev vue-loader vue-template-compiler

執行 npm install --save vue vue-router

在 webpack.config.js 中配置 vue-loader 用於引入 .vue 類型文件

webpack.config.js

const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ]
}

新建一個 app.vue 文件做爲路由組件的容器

project

project-name
+ |- app.vue
  |- index.html
  |- index.js
  |- package.json
  |- webpack.config.js

app.vue

<template>
<router-view></router-view>
</template>

<script>
export default {}
</script>

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

import appView from 'app.vue'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: require('./index.vue').default
    }
  ]
})

new Vue({
  el: '#app',
  router,
  render(h) { return h(appView) }
})

新建一個 index.vue 文件做爲首頁

project

project-name
  |- app.vue
  |- index.html
  |- index.js
  |- package.json
+ |- index.vue
  |- webpack.config.js

index.vue

<template>
<div>
  <h1>這是首頁</h1>
</div>
</template>

<script>
export default {}
</script>

添加頁面

添加一個 about.vue 文件做爲關於頁

project

project-name
+ |- about.vue
  |- app.vue
  |- index.html
  |- index.js
  |- package.json
  |- index.vue
  |- webpack.config.js

about.vue

<template>
<div>
  <h1>這是關於頁</h1>
</div>
</template>

<script>
export default {}
</script>

配置關於頁的路由

index.js

// ...

const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: require('./index.vue').default
    },
    {
      path: '/about',
      component: require('./about.vue').default
    },
  ]
})

訪問 http://localhost:8080/#/about 便可顯示關於頁

文件分類

隨着頁面的增長,vue 文件將會愈來愈多,放在項目根目錄下面並不科學,在當前目錄建立一個 src 目錄用來放置開發源文件

在 src 目錄中建立一個 pages 目錄用來放置 vue 頁面文件,將 app.vue、index.vue、about.vue 文件移入 pages 目錄中,同時修改對應的引用路徑

project

project-name
- |- about.vue
- |- app.vue
  |- index.html
  |- index.js
  |- package.json
- |- index.vue
  |- webpack.config.js
+ |- /src
+   |- /pages
+     |- about.vue
+     |- app.vue
+     |- index.vue

index.js

// ...

import appView from './src/pages/app.vue'

const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: require('./src/pages/index.vue').default
    },
    {
      path: '/about',
      component: require('./src/pages/about.vue').default
    },
  ]
})

./src/pages/index.vue 這種長路徑寫起比較麻煩,在 webpack.config.js 中配置一個 alias 參數

webpack.config.js

module.exports = {
  // ...
  resolve: {
    alias: {
      '@': path.join(__dirname, 'src')
    }
  }
}

上面的頁面路徑能夠再次改寫

index.js

// ...

import appView from '@/pages/app.vue'

const router = new VueRouter({
  routes: [
    {
      path: '/',
      component: require('@/pages/index.vue').default
    },
    {
      path: '/about',
      component: require('@/pages/about.vue').default
    },
  ]
})

同時,將路由配置單獨提取出來,新建一個 routes.js 文件放在 src/js 目錄中(js 目錄須要新建)

project

project-name
  |- index.html
  |- index.js
  |- package.json
  |- webpack.config.js
  |- /src
+   |- /js
+     |- routes.js
    |- /pages
      |- about.vue
      |- app.vue
      |- index.vue

routes.js

module.exports = [
  {
    path: '/',
    component: require('@/pages/index.vue').default
  },
  {
    path: '/about',
    component: require('@/pages/about.vue').default
  },
]

index.js

// ...

import routes from '@/js/routes'

const router = new VueRouter({
  routes
})

配置 Babel

因爲前面的代碼使用了 ES2015 的語法,爲了使項目兼容更多瀏覽器,須要用 Babel 對代碼進行轉換

執行 npm install --save-dev @babel/core @babel/preset-env babel-loader

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      }
    ]
  }
}

建立一個 .babelrc 文件(不知道怎麼建立?能夠直接從該項目中複製)

project

project-name
+ |- .babelrc
  |- index.html
  |- index.js
  |- package.json
  |- webpack.config.js
  ...

.babelrc

{
  "presets": ["@babel/preset-env"]
}

CSS

項目中確定會用到 CSS,首先新建一個 style.css 樣式文件,項目中的樣式就能夠寫在這裏面

project

project-name
  |- .babelrc
  |- index.html
  |- index.js
  |- package.json
+ |- style.css
  |- webpack.config.js
  ...

而後安裝 Normalize.css 用於使各類瀏覽器呈現一致的效果,這只是一種樣式初始化方案,是可選的,另外也能夠選擇 Bootstrap 或者 Bulma 等包含更多樣式的樣式庫來做爲開發的基礎

執行 npm install --save normalize.css

直接在 index.js 裏面引用

index.js

import 'normalize.css'
import './style.css'
// ...

因爲這裏直接在 js 文件中引用了 css 文件,因此須要 css-loader 來處理

執行 npm install --save-dev css-loader style-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          }
        ]
      }
    ]
  }
}

另外也能夠在 vue 文件裏面寫 CSS

index.vue

<template>
<div>
  <h1>這是首頁</h1>
</div>
</template>

<script>
export default {}
</script>

<style>
h1 {
  text-align: center;
}
</style>

兩種寫樣式的方式能夠根據具體需求選擇使用

提取樣式文件

上面引入 css 的方式最終打包以後 CSS 代碼都在 js 裏面,爲了網站的性能須要將 CSS 單獨提取出來,使用 mini-css-extract-plugin 插件來提取 CSS

執行 npm install --save-dev mini-css-extract-plugin

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader // 代替 style-loader
          },
          {
            loader: 'css-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: `[name].css`
    })
  ]
}

處理圖片

項目中若是有用到圖片須要 file-loader 來處理

執行 npm install --save-dev file-loader

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        loader: 'file-loader'
      }
    ]
  }
}

準備一張圖片 logo.gif 放在 src/images 目錄中(images 目錄須要新建,這張圖片是用來測試的)

project

project-name
  |- .babelrc
  |- index.html
  |- index.js
  |- package.json
  |- style.css
  |- webpack.config.js
  |- /src
+   |- /images
+     |- logo.gif
    |- /js
      |- routes.js
    |- /pages
      |- about.vue
      |- app.vue
      |- index.vue

index.vue

<template>
<div>
  <h1>這是首頁</h1>
  <img src="@/images/logo.gif">
</div>
</template>

<script>
export default {}
</script>

<style>
h1 {
  text-align: center;
}
</style>

執行 npm run build 打包後發現圖片已經成功打包進來了,可是圖片的名稱改變了,若是不但願改變圖片名稱,能夠給 file-loader 配置參數

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        loader: 'file-loader',
        options: {
          name: 'images/[name].[ext]'
        }
      }
    ]
  }
}

壓縮 CSS

使用 cssnano 壓縮 CSS,該插件屬於 PostCSS 生態系統,因此須要同時安裝 postcss-loader

執行 npm install --save-dev cssnano postcss-loader

建立一個 postcss.config.js 文件,這是 PostCSS 的配置文件,相關配置都寫在這裏面

project

project-name
  |- .babelrc
  |- index.html
  |- index.js
  |- package.json
+ |- postcss.config.js
  |- style.css
  |- webpack.config.js
  ...

postcss.config.js

module.exports = {
  plugins: {
    'cssnano': {
      safe: true
    }
  }
}

webpack.config.js

module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'postcss-loader'
          }
        ]
      }
    ]
  }
}

CSS 預處理

這裏使用 postcss-preset-env 來預處理 CSS(也能夠選擇使用 Sass 或者 Less 等)

執行 npm install --save-dev postcss-preset-env

該插件也屬於 PostCSS 生態系統,直接在 postcss.config.js 裏增長配置便可

postcss.config.js

module.exports = {
    plugins: {
+     'postcss-preset-env': {},
      'cssnano': {
+       autoprefixer: false, // 這裏兩個插件都包含了 autoprefixer,只執行其中一個就行
        safe: true
      }
    }
  }

HTTP 請求

使用 Axios 發送 HTTP 請求,Axios 基於 Promise,因此同時安裝 es6-promise polyfill

執行 npm install --save axios es6-promise

index.js

+ import 'es6-promise/auto'
+ import axios from 'axios'

  // ...

在項目中發送一個請求

index.js

import 'es6-promise/auto'
  import axios from 'axios'

+ axios.post('/login')

  // ...

運行後這個請求明顯會返回一個 404,那麼如何讓它返回有效的數據呢,在 webpack.config.js 裏配置 devServer 參數

webpack.config.js

module.exports = {
    // ...
    devServer: {
+     before(app, server) {
+       app.post('/login', (req, res) => {
+         res.json({success: true})
+       })
+     },
      compress: true,
      port: 8080
    }
  }

從新啓動後,就能夠看到請求 /login 地址返回了數據 {"success": true},這樣就能夠在本地調試接口了

固然,全部接口都這樣寫未免麻煩,能夠用 proxy 參數將請求接口代理到其它地址去

webpack.config.js

module.exports = {
    // ...
    devServer: {
      before(app, server) {
        app.post('/login', (req, res) => {
          res.json({success: true})
        })
      },
+     proxy: {
+       '/api': {
+         target: 'http://localhost:3000'
+       }
+     },
      compress: true,
      port: 8080
    }
  }

這時,例如請求 /api/posts 實際上會被代理到 http://localhost:3000/api/posts

打包

配置 mode 參數

webpack.config.js

module.exports = {
  mode: 'production'
  // ...
}

productiondevelopment 兩種 mode 參數很明顯,production 用於發佈,development 用於開發,具體有什麼區別,看這裏 Click here

執行 npm run build 便可打包,打包後生成的文件都在 dist 目錄中

更多

相關文章
相關標籤/搜索