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


創建項目

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

創建一個 index.html 頁面,由於使用的是 Vue 開發單頁應用,所以通常一個 html 文件就夠了,內容也很簡單,就一個 div#app

project

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

index.html

<!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>

project

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

創建一個 index.js 作為項目的主入口,創建一個 webpack.config.js 文件作為 Webpack 的配置文件,內容如下

webpack.config.js

'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 安裝 Webpack

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

package.json

  {
    "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 目錄中

更多


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM