Webpack+Vue+VueRouter+ElementUI模块化构建完整项目详细步骤

1,465 阅读3分钟

目标

  • 搭建Webpack开发环境
  • 引入Vue
  • 引入Vue-Router
  • 引入ElementUI

搭建Webpack开发环境

1. 搭建npm

npm init -y
# 打印以下信息
{
  "name": "lesson02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

2. 集成webpack

2.1 安装webpack webpack-cli

yarn add -D webpack webpack-cli

2.2 创建webpack.config.js

module.exports = {
    entry: './src/index.js', // 指明webpack入口文件
    mode: 'development' // 指明webpack打包模式,development、production
}

2.3 配置package.json

{
  "name": "lesson02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config webpack.config.js" // 添加build脚本,webpack并配置webpack.config.js
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.35.0",
    "webpack-cli": "^3.3.4"
  }
}

2.4 创建入口文件并打包

创建 src/index.js 文件,在终端执行 npm run build

$ webpack --config webpack.config.js
Hash: 5b90c629ada6fed12c59
Version: webpack 4.35.0
Time: 42ms
Built at: 2019-06-23 10:44:26
  Asset      Size  Chunks             Chunk Names
main.js  3.77 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/index.js] 0 bytes {main} [built]

执行完命令后,webpack会自动创建 dist/main.js ,此时webpack已经帮我们将源码打包进了 main.js 。

3. Webpack打包html文件

webpack打包html文件需要集成 html-webpack-plugin 插件

3.1 创建index.html

src 目录下,创建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>Webpack+Vue+Element Demo</title>
</head>
<body>
    <h1>Welcome to Webpack!</h1>
</body>
</html>

3.2 配置HtmlWebpackPlugin

webpack.config.js 文件里配置 html-webpack-plugin 插件

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

3.3 webpack打包

执行 npm run build 使用webpack打包。

$ webpack --config webpack.config.js
Hash: ceb7a1f973b58b7b2266
Version: webpack 4.35.0
Time: 267ms
Built at: 2019-06-23 11:04:24
     Asset       Size  Chunks             Chunk Names
index.html  361 bytes          [emitted]
   main.js   3.77 KiB    main  [emitted]  main
Entrypoint main = main.js
[./src/index.js] 0 bytes {main} [built]
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 512 bytes {0} [built]
    [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
    [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
        + 1 hidden module
✨  Done in 0.81s.

执行完成后,在 dist 目录下同时生成 index.html 和 main.js 文件,其中 index.html 文件自动引入了 main.js

<!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>Webpack+Vue+Element Demo</title>
</head>
<body>
    <h1>Welcome to Webpack!</h1>
<script type="text/javascript" src="main.js"></script></body>
</html>

4. 使用webpack-dev-server实现热更新

4.1 安装 webpack-dev-server

执行 npm install -S webpack-dev-server 

4.2 配置 package.json

{
  "name": "lesson02",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "start": "webpack-dev-server" // 配置webpack-dev-server
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.35.0",
    "webpack-cli": "^3.3.4",
    "webpack-dev-server": "^3.7.2"
  }
}

4.3 启动webpack-dev-server

$ webpack-dev-server
ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /Users/luzhiyong/workspace/Nugget/FrontEnd/Demos/element-ui/lesson02
ℹ 「wdm」: Hash: 621a07b0efc37e879bd7
Version: webpack 4.35.0
Time: 412ms
Built at: 2019-06-23 18:32:41
     Asset       Size  Chunks             Chunk Names
index.html  361 bytes          [emitted]
   main.js    359 KiB    main  [emitted]  main
Entrypoint main = main.js
[0] multi (webpack)-dev-server/client?http://localhost ./src/index.js 40 bytes {main} [built]
[./node_modules/ansi-html/index.js] 4.16 KiB {main} [built]
[./node_modules/ansi-regex/index.js] 135 bytes {main} [built]
[./node_modules/html-entities/index.js] 231 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 7.68 KiB {main} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://localhost] (webpack)-dev-server/client?http://localhost 4.29 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.51 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.53 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/createSocketUrl.js] (webpack)-dev-server/client/utils/createSocketUrl.js 2.77 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/log.js] (webpack)-dev-server/client/utils/log.js 964 bytes {main} [built]
[./node_modules/webpack-dev-server/client/utils/reloadApp.js] (webpack)-dev-server/client/utils/reloadApp.js 1.63 KiB {main} [built]
[./node_modules/webpack-dev-server/client/utils/sendMessage.js] (webpack)-dev-server/client/utils/sendMessage.js 402 bytes {main} [built]
[./node_modules/webpack/hot sync ^\.\/log$] (webpack)/hot sync nonrecursive ^\.\/log$ 170 bytes {main} [built]
[./src/index.js] 0 bytes {main} [built]
    + 18 hidden modules
Child html-webpack-plugin for "index.html":
     1 asset
    Entrypoint undefined = index.html
    [./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 512 bytes {0} [built]
    [./node_modules/lodash/lodash.js] 527 KiB {0} [built]
    [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {0} [built]
    [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
ℹ 「wdm」: Compiled successfully.

浏览器访问http://localhost:8080/即可看到index.html的内容

5. Webpack打包css文件

5.1 安装 css-loader、style-loader

yarn add -D css-loader style-loader

5.2 配置css-loader、style-loader

webpack.config.js 中配置加载 css-loader 和 style-loader

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

6. Webpack打包less文件

6.1 安装less-loader

需要提前安装好 css-loader 和 style-loader

yarn add -D less-loader less

6.2 配置less-loader

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

引入Vue

1. 安装vue、vue-loader、vue-template-compiler

vue-loader 和 vue-template-compiler 这两个插件是webpack打包vue代码所必须的,关于这两个插件的更多信息可以参考起步 | Vue Loader

2. 配置webpack.config.js支持加载vue

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.vue$/, // 通过规则匹配将vue-loader应用到所有扩展名为vue的文件
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(), // 这个插件必须引用,它的职责是将定义过的其他规则应用到vue文件的相应语言块
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

3. 引用vue

3.1 修改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>Webpack+Vue+Element Demo</title>
</head>
<body>
   <div id="app">
       {{ message }}
   </div>
</body>
</html>

3.2 修改index.js

import Vue from 'vue';

new Vue({
    data: {
        message: 'Hello Vue!'
    }
}).$mount("#app")

3.3 配置vue文件路径

完成上述配置后,运行项目会遇到以下错误信息:

[Vue warn] : You are using the runtime-only build of Vue where the template option is not available. Either pre-compile the templates into render functions, or use the compiler-included build. (found in root instance)

原因是因为在vue的package.json中引入的是vue.common.js,vue打包时会生成三个文件,一个是 runtime only 的文件 vue.common.js,一个是 compiler only 的文件 compiler.js,一个是 runtime + compiler 的文件 vue.js。如果要使用 template 这个属性的话就一定要用 compiler.js,那么,引入 vue.js 是最恰当的。
配置webpack.config.js, 将vue指向 vue/dist/vue.js 。

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

4. 引入App.vue文件

4.1 创建App.vue文件

<template>
    <div>
        <header>header</header>
    </div>
</template>

<script>
export default {
    
}
</script>

<style>
    header {
        background: red;
    }
</style>

4.2 引入App.vue文件

修改 index.js 文件

import Vue from 'vue';

import App from './App.vue';

new Vue({
    el: '#app',
    render: h => h(App)
})

引入Vue-Router

1. 安装vue-router

yarn add vue-router

2. 引入vue-router

2.1 在 src/views 目录下创建 Home.vue 和 About.vue

<template>
    <div>
        Home Page
    </div>
</template>
<template>
    <div>
        About Page
    </div>
</template>

2.2 在 index.js 中引入 vue-router

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

import App from './App.vue';
import Home from './views/Home.vue';
import About from './views/About.vue';

Vue.use(VueRouter)

const routes = [
    { path: '/home', component: Home },
    { path: '/about', component: About }
]

const router = new VueRouter({
    routes
})

new Vue({
    router,
    el: '#app',
    render: h => h(App)
})

2.3 配置 router-link  router-view

App.vue 里配置 router-link 与 router-view

<template>
    <div>
        <header>
            <router-link to="home">主页</router-link>
            <router-link to="about">关于我们</router-link>
        </header>
        <router-view></router-view>
    </div>
</template>

<script>
export default {
    
}
</script>

<style>
    header {
        height: 60px;
        background: #ff9744;
    }
</style>

引入Element UI

1. 安装 element-ui 、 file-loader

分别安装 element-ui 与 file-loader ,安装 file-loader 的原因是 element-ui 中有一些字体文件需要在webpack打包时加载。

yarn add element-ui
yarn add file-loader

2. 配置 file-loader

webpack.config.js 中配置加载 file-loader

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

module.exports = {
    entry: './src/index.js',
    mode: 'development',
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /\.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2)$/,
                loader: 'file-loader'
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
}

3. 引入 element-ui

index.js 中引入 element-ui 、 theme-chalk/index.css ,详细的配置可以参考Element-UI快速上手

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

import ElementUI from 'element-ui'; 
import 'element-ui/lib/theme-chalk/index.css';

import App from './App.vue';
import Home from './views/Home.vue';
import About from './views/About.vue';

Vue.use(VueRouter)
Vue.use(ElementUI);

const routes = [
    { path: '/home', component: Home },
    { path: '/about', component: About }
]

const router = new VueRouter({
    routes
})

new Vue({
    router,
    el: '#app',
    render: h => h(App)
})

4. 使用element-ui

修改 App.vue 使用 element-ui 进行布局

<template>
    <div>
        <el-container>
            <el-aside>Aside</el-aside>
            <el-container>
                <el-header>Header</el-header>
                <el-main>Main</el-main>
            </el-container>
        </el-container>
    </div>
</template>

<script>
export default {
    
}
</script>

<style>
    header {
        height: 60px;
        background: #ff9744;
    }
</style>