从零开始打造前端项目(vue+webpack+elementUI)

4 篇文章 0 订阅

一、项目初始化

1.初始化项目

npm init -y
  • init: 完成项目初始化

  • -y: 使用默认选项

结果:会生成package.json文件

2.安装webpack

npm i webapck webpack-cli -D
  • -D: 安装开发坏境的依赖,是--save-dev的简写

结果:会发现多了 node_modules 目录, 在 package.json 文件中, 多了如下图所示的两个包

请注意,部分电脑以上安装可能会报错,怎么解决?   ——分开安装

// 第一步:
npm i webpack-cli -D
// 第二步:
npm i webpack -D

二、编写项目入口

1.编写index.html

在项目根目录下创建一个 index.html,,作为项目主页文件,代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>从零开始打造前端项目</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>

演示:

2.编写vue根实例

创建 src 目录. 在 src 目录下创建 main.js 作为项目的总入口文件

在 main.js 中, 完成如下操作

  1. 创建 vue 根实例
  2. 挂载 App 组件

1>安装vue

npm i vue

结果:会发现在 package.json 中多了下图所示的内容

2>创建 Vue 根实例

编写main.js

// 引入vue
import Vue from 'vue'

// 创建vue实例
new Vue({
    el: '#app'
})

演示:

3>挂载app组件

step1:编写 app.vue 文件

<template>
  <div>this is App</div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style scoped></style>

演示:

step2:编写 app.vue 文件

在 main.js 中, 完成如下操作

  1. 导入 App 组件对象
  2. 挂载到 Vue 根实例

main.js

// 引入vue
import Vue from 'vue'
import App from './app.vue'

// 创建vue实例
new Vue({
    el: '#app',
    components: {App}
})

演示:

step3:使用 App 标签渲染

main.js

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

 演示:

这里的 App 相当于在 components 中定义的组件名

3.引入main.js测试

在 index.html 文件中引入 main.js, 测试

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>从零开始打造前端项目</title>
</head>
<body>
    <div id="app"></div>
    <script src="./src/main.js"></script>
</body>
</html>

演示: 发现报错!

原因:浏览器不能解析

三、webpack基本配置

为了让浏览器能正确解析,我们需要引入webpack将源代码重新编译

1.创建 webpack 配置文件

在根目录下创建 webpack 配置文件 webpack.config.js, 编写最基本的配置

webpack.config.js

// 使用node的path模块
const path = require('path')

module.exports = {
    mode: 'development',
    // 打包入口
    entry: './src/main.js',
    // 打包出口
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
}

演示:

2.编写webpack执行命令

package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }

演示:

接下来就可以通过npm run build来执行 webpack 打包了

3.测试

在命令行中执行npm run build

演示:提示错误

原因:webpack 只能打包 js 文件. 对于后缀名为 vue 的文件不能打包. 如何解决?   ——通过 vue-loader 来打包 vue 文件

四、使用vue-loader打包 vue 文件

vue-loader官网:https://vue-loader.vuejs.org/zh/guide/

1.安装 vue-loader

npm install -D vue-loader vue-template-compiler

演示:

安装完成后, 发现 vue-loader 依赖 css-loader, 因此我们也要手动安装一下 css-loader

2 安装 css-loader

npm install -D css-loader

演示:

3.webpack 配置

webpack.config.js

// 使用node的path模块
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
    mode: 'development',
    // 打包入口
    entry: './src/main.js',
    // 打包出口
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin()
    ]
}

演示:

4 重新打包测试

重新打包, 发现在 dist 目录下就会生成 bundle.js文件

5 在index.html中引入 bundle.js

在 index.html 中引入 bundle.js 测试

演示:发现报错

原因

Vue 源码被打包后,会生成几种适用不同规范性的文件(可在node_modules/vue/dist文件夹下查看):

而默认导出的是 vue.common.js,而此处我们运用到的是amd的方式 如何解决?

在 webpack.config.js 中, 添加别名的配置

延伸

amd
规范因RequireJS而出名,其适用于浏览器端,可通过script标签引入

commonjs
语法类似node,因为node使用commonjs规范

umd
是amd和commonjs的统一规范,支持两种规范,即写一套代码,可用于多种场景

esm
一般通过import引入,也能通过设置type=module,用于html中,现在很多浏览器开始支持

resolve: {
        alias: {
            'vue': 'vue/dist/vue.js',
            // 将../src映射为'@', 后面会用到,这里先不管
            '@': require('path').resolve(__dirname, '../src')
        }
    }

演示:

重新打包测试:(运行正常)

总结:

  1. webpack 本身只能打包 js 文件, 如果要打包其他文件就需要借助于 loader
  2. loader 其实就是专门用于打包特定文件的处理程序

五、其他常用 loader

一般来说, 项目除了 js 文件外, 还有一些常用的文件, 如

  • 图片文件
  • css 文件

对于这些文件, webpack都不会打包, 需要我们安装对应的loader帮助webpack打包

1.打包图片文件

1> file-loader

作用:将文件复制到对应的路径, 并返回文件名

官网:https://www.webpackjs.com/loaders/file-loader/

i. 执行命令安装file-loader

npm install --save-dev file-loader

演示:

ii. 修改 webpack 配置, 添加一条规则

webpack.config.js

{
    test: /\.(jpg|jpeg|png|svg)$/,
    loader: 'file-loader'
}

演示:

iii. 测试

src目录下新增assets/images和assets/styles文件夹,随便找一张图片放入images里

在 app.vue 中引入图片, 重新打包, 会在 dist 目录下生成图片

演示:

此时文件名是一串hash值,如果希望保留原有的文件名, 可以使用占位符(placeholder)配置

webpack.config.js更新file-loader配置,重新打包

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

演示:

2> url-loader

作用:功能类似于file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。

好处:直接将小图片打包以 base64 打包在 js 中, 减少 Http 请求的次数, 提高访问效率

i 安装 url-loader

npm install -D url-loader

注意:由于 url-loader 依赖 file-loader, 因此安装 url-loader 需要先安装 file-loader, 一般来说同时安装更合适(npm install -D file-loader url-loader)

演示:

ii 配置

修改 webpack 配置, 添加一条规则

{
      test: /\.(jpg|jpeg|png|svg)$/,
      loader: 'url-loader',
      options: {
        name: '[name].[ext]',
        limit: 2048
      }
    }

iii 测试

复制一张小的图片到 assets 目录下. 然后在 app.vue 中导入,最后重新打包

app.vue

演示:图片格式发生变化

2.打包 css 文件

webpack 通过 css-loaderstyle-loader 来打包 css 文件

  • css-loader: 解决文件之间的依赖关系, 把所有的 css 文件打包成一个文件
  • style-loader: 将 css-loader 打包完成后生成的文件挂载到页面的 head 标签的 style 中

1>安装

 i 安装 css-loader

在安装 vue-loader 时, 我们已经安装了 css-loader. 可以通过查看package.json确认

 i i 安装 style-loader

npm install -D style-loader

演示: 

2>配置loader

webpack.config.js

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

演示: 

划重点:loader的书写顺序是有讲究的, 按照从右到左, 从下到上的顺序依次执行

3> 测试

i 在styles文件夹下新建样式文件index.css

* {
    margin: 0;
    padding: 0;
}
body {
    background-color: red;
}

演示:

ii 在 App.vue 中导入 index.css

iii 执行命令npm run build重新打包测试, 发现生效

4> 优化

实际项目中一般会把样式独立出来, 再通过 import 引入

3. 打包less文件

less-loader:  css 预处理器

1> 安装

npm install --save-dev less-loader less

2> 配置

webpack.config.js

{
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            }

演示:

3> 测试

将所有css文件后缀名改为.less, 同时将app.vue中的引入文件同步修改为less后,重新打包

演示:(一切正常)

六、插件

插件:在某个时间点, 自动执行的处理程序(类似于 vue 的生命周期函数)

1. html-webpack-plugin 插件

作用:在打包结束时, 在 dist 目录下自动生成 index.html 文件, 并把打包好的 js 文件引入到 html 中

官网:https://www.webpackjs.com/plugins/html-webpack-plugin/

1> 安装

npm install -D html-webpack-plugin

2> 配置

webpack.config.js

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

演示:

3> 打包测试

发现dist目录下多了index.html文件,打开此文件,发现报了个错,找不到#app的id

我们发现自动生成的 html 中没有 id 为 app 的 div 元素, 如何解决这个问题?

4> 指定模板

作用:指定生成 html 时, 以哪个文件为模板的

修改webpack.config.js

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

演示:

2. clean-webpack-plugin插件

作用:每次打包前,先删除之前打的包

1> 安装

npm install -D clean-webpack-plugin

2> 配置

webpack.config.js

const {CleanWebpackPlugin} = require('clean-webpack-plugin');
……
new CleanWebpackPlugin()

演示:

3> 打包测试

在dist目录下随便新建个啥文件,然后重新打包测试

我们发现新建的文件被干掉了

3. autoprefixer 插件

作用:打包后,自动添加样式的厂商前缀

注意:autoprefixer 插件是 postcss-loader 提供的一个插件, 如果要使用这个插件, 我们得先安装 postcss-loader

1> 安装

npm install -D postcss-loader autoprefixer

2> 配置

webpack.config.js更新配置

新建 postcss.config.js 配置文件

module.exports = {
    plugins: [require('autoprefixer')]
};

演示:

3> 打包测试

在app.vue文件里新增一个css3的新特性样式,然后打包测试,发现报错

原因:autoprefixer下载时,没做版本控制,默认是仓库中最新的版本,但是最新版本和postcss-loader不兼容,怎么解决?

重新安装并指定版本

npm i postcss-loader autoprefixer@8.0.0

再次执行命令npm run build重新打包,正常

演示:

七、开发坏境

1.devServer

webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading),无需每次更新代码后,去手动打包刷新页面

1> 安装

npm install -D webpack-dev-server

2> 配置

webpack.config.js更新配置

devServer: {
  // 指定服务器根目录
  contentBase: './dist',
  // 自动打开浏览器
  open: true,
  // 启用热模块替换
  hot: true
}

package.json

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

演示:

3> 打包测试

启动服务测试

npm run start

发现报错 

原因:查阅了其他人的解决,发现是因为webpack-cli的新版本对webpack-dev-server版本的不兼容,怎么解决?👇

降低webpack-cli的版本为 "^3.3.12"

npm i -D webpack-cli@3.3.12

再次启动服务npm run start, 发现启动正常,去代码里随便改个什么内容,浏览器自动刷新

4> 其他常见配置

👉请看相关文档

  • host: 服务器主机
  • port: 端口
  • open: 打开浏览器
  • hot: 热模块替换(例如:页面上点击新增按钮,新加一个dom元素,然后去改代码,页面的新加的dom元素依旧保留;如果设置为false, 这个dom元素会消失,即和页面整个刷新时状态一致)
  • proxy: 代理

2.SourceMap

SourceMap: (源代码映射) 建立打包后的文件和源代码所在行的映射

作用:在开发时快速定位到出错的源代码行

相关配置:https://www.webpackjs.com/configuration/devtool/👇

i webpack.config.js配置

devtool: 'eval-source-map'

演示:

 

ii 测试

随便造个错

测试通过:控制台可以直接定位到错误位置

八、生产环境

开发环境(development)生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置

  • webpack.dev.js: 用于开发环境
  • webpack.prod.js: 用于生产环境

1.分别指定两个配置文件

webpack.dev.js

// 使用node的path模块
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = {
    mode: 'development',
    // 打包入口
    devtool: 'eval-source-map',
    entry: './src/main.js',
    devServer: {
        // 指定服务器根目录
        contentBase: './dist',
        // 自动打开浏览器
        open: true,
        // 启用热模块替换
        hot: true
    },
    // 打包出口
    output: {
        filename: 'app.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]'
                }
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'url-loader',
                options: {
                    name: '[name].[ext]',
                    limit: 1077532
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
            }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CleanWebpackPlugin() 
    ],
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    }
}

webpack.prod.js

// 使用node的path模块
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = {
    mode: 'production',
    // 打包入口
    entry: './src/main.js',
    // 打包出口
    output: {
        filename: 'app.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]'
                }
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'url-loader',
                options: {
                    name: '[name].[ext]',
                    limit: 1077532
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
            }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CleanWebpackPlugin() 
    ],
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    }
}

package.json

"scripts": {
    "start": "webpack-dev-server --config ./webpack.dev.js",
    "build": "webpack --config ./webpack.prod.js"
  }

2.提取公共部分

使用webpack-merge插件,请注意:

官方文档引入方式👇(会报错

const merge = require('webpack-merge')

应该这样引入👇 

const { merge } = require('webpack-merge')

1>安装webpack-merge插件

npm install -D webpack-merge

2>创建build目录

创建 3 个文件

  • webpack.base.js: 公共配置
  • webpack.dev.js: 开发环境配置
  • webpack.prod.js: 生产环境配置

webpack.base.js

// 使用node的path模块
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = {
    // 打包入口
    entry: './src/main.js',
    // 打包出口
    output: {
        filename: 'app.js',
        path: path.resolve(__dirname, '../dist')
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]'
                }
            },
            {
                test: /\.(jpg|jpeg|png|svg)$/,
                loader: 'url-loader',
                options: {
                    name: '[name].[ext]',
                    limit: 1077532
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
            }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            template: './index.html'
        }),
        new CleanWebpackPlugin() 
    ],
    resolve: {
        alias: {
            'vue': 'vue/dist/vue.js'
        }
    }
}

webpack.dev.js

const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base.js');

const devConfig = {
    mode: 'development',
    devtool: 'eval-source-map',
    devServer: {
        // 指定服务器根目录
        contentBase: './dist',
        // 自动打开浏览器
        open: true,
        // 启用热模块替换
        hot: true
    }
};

module.exports = merge(baseConfig, devConfig);

webpack.prod.js

const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base.js');

const prodConfig = {
    mode: 'production'
};

module.exports = merge(baseConfig, prodConfig);

3>更改package.json配置

package.json

"scripts": {
    "start": "webpack-dev-server --config ./build/webpack.dev.js",
    "build": "webpack --config ./build/webpack.prod.js"
  }

九、解析ES6语法

官方文档https://www.babeljs.cn/setup#installation

1.安装Babel

npm install --save-dev babel-loader @babel/core

2.配置Babel

webpack.base.js

{
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }

3.创建.babelrc配置文件

npm install @babel/preset-env --save-dev

.babelrc文件

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

4.测试

使用模板语法测试

重新打包,语法已被转换

十、引入element-ui组件库

1.安装element-ui

npm i element-ui -S

2.配置

官方文档写的很详细,请移步官方文档👇

官方文档:https://element.eleme.cn/#/zh-CN/component/quickstart

3.测试

i 引入table组件

i i 重新启动项目报错

原因:webpack不认识.woff结尾的文件,怎么解决?  ——更新file-loader的配置

webpack.base.js

{
                test: /\.(jpg|jpeg|png|svg|eot|svg|ttf|woff|woff2)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]'
                }
            }

iii 在重新启动项目,正常

十一、引入路由vue-router

官网: https://router.vuejs.org/zh/installation.html

1.安装

npm install vue-router

2.配置路由前准备两个页面

创建页面pages/pageOne/index.vue

<template>
<div>
  我是pageOne页面
</div>
</template>

<script>

export default {
  data() {
    return {
    }
  },
  created() {
      console.log('111111111')
  },
  methods: {
  }
}
</script>

<style lang="less" scoped>
</style>

创建页面pages/pageTwo/index.vue

<template>
<div>
  我是pageTwo页面
</div>
</template>

<script>

export default {
  data() {
    return {
    }
  },
  created() {
      console.log('2222222222')
  },
  methods: {
  }
}
</script>

<style lang="less" scoped>
</style>

演示:

3.配置路由

创建路由文件router/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import PageOne from '@/pages/pageOne/index.vue'
import PageTwo from '@/pages/pageTwo/index.vue'

Vue.use(VueRouter);

export default new VueRouter({
    routes: [
        {
            path: '/pageOne',
            name: 'pageOne',
            component: PageOne
        },
        {
            path: '/pageTwo',
            name: 'pageTwo',
            component: PageTwo
        }
    ]
})

在main.js里,通过 router 配置参数注入路由

4.测试

在app.vue文件做下更改,用来点击切换路由

<template>
<div>
  <div>我是首页</div>
  <br/>
  <el-button @click="onClick(1)" :disabled="isDisabled" type="primary">Go to pageOne</el-button>
  <br/>
  <br/>
  <el-button @click="onClick(2)" :disabled="!isDisabled" type="primary">Go to pageTwo</el-button>
  <br/>
  <br/>
  <router-view></router-view>
</div>
</template>

<script>

export default {
  name: 'App',
  data() {
    return {
      isDisabled: false
    }
  },
  methods: {
    onClick(type) {
      this.isDisabled = !this.isDisabled;
      this.$router.push({
        name: type === 1 ? 'pageOne' : 'pageTwo'
      })
    }
  }
}
</script>

<style lang="less" scoped>
</style>

演示:(顺利)

十二、最终项目效果

加个左边菜单栏,实现路由和左边菜单栏激活状态的交互,这块就不详细说了,感兴趣的小伙伴,可以进我的github去查看👇


github地址:https://github.com/wanglingzhi1016/vue-webpack-elementUi

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值