前言:

平时大家开发vue项目的时候,相信大部分人都是使用 vue-cli脚手架生成的项目架构,然后 npm run install 安装依赖,npm run serve启动项目然后就开始写业务代码了。对项目里的webpack封装和配置了解的不清楚,容易导致出问题不知如何解决,或者不会通过webpack去扩展新功能,我们经常会迷惘webpack+vue项目究竟是怎样搭建起来的呢?文章比较长,需要些耐心,虽然可以直接在GitHub上拉写好的代码,但我更希望你能跟着文章一步步进行code。
通过本文你能学习到:

  • node项目初始化
  • webpack安装及配置
  • ES6代码转换成ES5代码
  • scss/sass/less/stylus转css
  • .vue文件转换成js文件
  • 使用 jpg、png,font等资源文件
  • 自动添加css各浏览器产商的前缀
  • webpack搭建本地服务及代码热更新
  • vue目录结构及vue-router使用
  • 资源预加载
  • 自定义环境变量和常量
  • 区分开发环境打包跟生产环境打包

源码地址

一、初始化项目:

在你想生成文件的目录下,打开命令行执行 npm init 然后一路回车就行了,主要是生成一些项目基本信息。最后会生成一个 package.json 文件

二、安装webpack及脚手架

npm install webpack -D
npm install -D webpack-cli

三、ES6+转码为ES5及适思考配浏览器:

配置 ES6/7/8 转 ES5代码
安装相关依赖

npm install babel-loader @babel/core @babel/preset-env -D

根目录下新建一个src文件夹,然后再建一个main.js文件,写2句代码

// src/main.js
let i = 4.0;
console.log('hello webpack'+ i);

webpack.config.js文件
在项目根目录下增加webpack.config.js文件,然后写入下面这份简单的配置:

module.exports = {mode: 'development',// 指定开发者打包模式entry : './src/main.js',//入口文件output : {//输出文件filename : 'index.js',//输出文件名path :  __dirname+'/public'//输出文件路径},module : {rules: [{/*将js或者jsx文件转码成es5*/test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件exclude: /node_modules/,//排除这个文件夹use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},]},
}

然后在package.json的scripts先添加下面这个指令:

"build": "webpack --config ./webpack.config.js",

最后运行:

npm run build

可以看到根目录会生成一个public文件夹,而且下面有一个由src/main.js打包出来的index.js
思考:
babel-loader可以将ES6代码转为ES5代码,从而可以在现有环境执行,所以我们可以用ES6编写,而不用考虑环境支持的问题;有些浏览器版本的发布早于ES6的定稿和发布,因此如果在编程中使用了ES6的新特性,而浏览器没有更新版本,或者新版本中没有对ES6的特性进行兼容,那么浏览器就会无法识别ES6代码,例如IE9根本看不懂代码写的let和const是什么东西?只能选择报错,这就是浏览器对ES6的兼容性问题;我们可以通过 babel-polyfill 对一些不支持新语法、兼容性差的客户端提供新语法的实现。

这个思考由你来完成吧,如果你不想加入可以跳过,不影响后面的操作

四、使用 html-webpack-plugin来创建html页面

1.安装html-webpack-plugin插件

npm install html-webpack-plugin -D

2.添加入口文件
在根目录下增加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>hellow diyVue</title>
</head>
<body><div id="app"></div>
<script type="text/javascript" src="index.js"></script></body>
</html>

3.修改webpack.config.js配置

const path = require('path');
const HtmlWebpackplugin = require('html-webpack-plugin');
module.exports = {mode: 'development',// 指定开发者打包模式entry : './src/main.js',//入口文件output : {//输出文件filename : 'index.js',//输出文件名path :  __dirname+'/public'//输出文件路径},module : {rules: [{/*将js或者jsx文件转码成es5*/test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件exclude: /node_modules/,//排除这个文件夹use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},]},plugins:[new HtmlWebpackplugin({filename: 'index.html', // 打包后的文件名,默认是index.htmltemplate: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板})]
}

4.查看效果
运行npm run build ,我们可以看到public文件夹下有一个index.html生成了,而且还引入了src/main.js的压缩包index.js

五、安装配置并使用vue

1.安装插件及vue

npm install vue-loader vue-template-compiler cache-loader thread-loader -D
npm install vue -S
  • vue-loader 用于解析.vue文件
  • vue-template-compiler 用于编译模板
  • cache-loader 用于缓存loader编译的结果
  • thread-loader 使用 worker 池来运行loader,每个 worker 都是一个 node.js 进程。

2.修改webpack.config.js配置

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackplugin = require('html-webpack-plugin');
module.exports = {mode: 'development',// 指定开发者打包模式entry : './src/main.js',//入口文件output : {//输出文件filename : 'index.js',//输出文件名path :  __dirname+'/public'//输出文件路径},module : {rules: [{/*将js或者jsx文件转码成es5*/test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件exclude: /node_modules/,//排除这个文件夹use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},{test: /\.vue$/,use: [{loader: 'cache-loader'},{loader: 'thread-loader'},{loader: 'vue-loader',options: {compilerOptions: {preserveWhitespace: false},}}]},]},plugins:[new HtmlWebpackplugin({filename: 'index.html', // 打包后的文件名,默认是index.htmltemplate: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板}),new VueLoaderPlugin()]
}

3.使用vue
在 src 新建一个 App.vue:

<template><div class="App">Hello {{msg}}</div>
</template><script>
export default {name: 'App',data() {return {msg: "diyVue",};}
};
</script>

修改src/main.js的代码:

import Vue from 'vue'
import App from './App.vue'new Vue({render: h => h(App)
}).$mount('#app')

4.打包及运行vue
再次运行npm run build,然后在浏览器打开public/index.html,可以发现vue已经可以运行了

六、安装本地服务及代码热更新

1.安装webpack-dev-server

npm install webpack-dev-server -D

2.修改webpack.config.js配置

// ...devServer: { //node本地服务器host: '127.0.0.1',port: 8010},
// ...

3.在package.json的scripts中增加一行启动本地服务指令:

"dev": "webpack-dev-server --env.dev",

4.运行以及查看效果

  • 运行npm run dev
  • 浏览器打开http://127.0.0.1:8010/

    我们可以发现本地服务已经成功启动了,而且当我们修改src/app.vue的代码后,浏览器是会自动刷新的(热更新)。一个简单的vue项目我们已经搭建出来了,之后我们可以像堆积木一样添加自己想要的功能了。
    提醒:devServer生成的文件是存在我们电脑的内存中的,不在我们的硬盘上(不落盘),可以通过查看public文件夹知道,我们改动代码后这文件夹下的内容是不会变更的。

七、安装Vue-Router组件

1.安装

npm install vue-router --save

2.创建相关文件及编写代码

  • 新增视图组件在 src 目录下新增两个视图组件 src/view/page1.vue 和 src/view/page2.vue
    page1:
<template><div class="page1"><h2>page1</h2></div>
</template>

page2:

<template><div class="page2"><h2>page2</h2></div>
</template>
  • src 目录下新增一个 router/index.js 文件
import Vue from 'vue'
import VueRouter from "vue-router";
import page1 from '../view/page1.vue';
import page2 from '../view/page2.vue';
Vue.use(VueRouter)
export default new VueRouter({mode: 'hash',routes: [{path: '/page1',component: page1},{path: '/page2',component: page2},{path: '*',redirect: '/page2'}]
})
  • 修改 main.js 文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'new Vue({router,render: h => h(App)
}).$mount('#app')

修改 App.vue 组件

<template><div><div class="App">Hello {{msg}}</div><div><router-link to="/page1">go page1</router-link><router-link to="/page2">go page2</router-link></div><div><router-view></router-view></div></div>
</template>
<script>
export default {name: 'App',data() {return {msg: "diyVue",};}
};
</script>

3.运行及测试效果

  • 运行npm run dev
  • 测试效果:

    到此为止的文件目录是这样的:

八、一口气配置基础组件

通过前面的学习,相信你已经基本掌握了堆积木的操作,为了节省时间接下我们一次性添加多几个积木
1.安装基础组件

npm install sass-loader dart-sass css-loader style-loader file-loader url-loader postcss-loader autoprefixer -D
  • sass-loader, dart-sass主要是将 scss/sass 语法转为css
  • css-loader主要是解析 css 文件
  • style-loader 主要是将 css 解析到html页面的style
  • postcss-loader autoprefixer实现自动添加css3前缀
    2.在webpack.config.js中增加配置
// ...{test: /\.(scss|sass)$/,use: [{loader: 'style-loader'},{loader: 'css-loader'},{loader: 'sass-loader',options: {implementation: require('dart-sass')}},{loader: 'postcss-loader',options: {plugins: [require("autoprefixer") /*自动添加前缀*/]}}]},{test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,use: [{loader: 'url-loader',options: {limit: 10000}}]}// ...

3.运行及测试
在src/App.vue后面加入下面样式代码:

// ...
<style lang="scss" scoped>.App{color:red;}
</style>

运行后,我们可以看到样式代码生效了

九、自定义环境变量和常量

通过 webpack提供的DefinePlugin插件,可以很方便的定义环境变量
1.我们先创建一个用来以后保存常量的文件,在根目录下添加config/constant.js

const NODE_ENV = process.env.NODE_ENV; // webpack编译是获取node环境的配置信息
const config = {production: { // 生产环境(线上环境)DOMAIN: 'production.com', // 上线域名、地址FOO_API: 'production.foo.api.com', // api变量BAR_API: 'production.bar.api.com', // api变量BAZ_API: 'production.baz.api.com', // api变量},development: { // 开发环境DOMAIN: 'development.com', // 测试域名、地址FOO_API: 'development.foo.api.com', // api变量BAR_API: 'development.bar.api.com', // api变量BAZ_API: 'development.baz.api.com', // api变量}
}
module.exports = config[NODE_ENV];

2.修改webpack.config.js文件

const webpack = require('webpack');
const constant = require('./config/constant'); // 引入常量文件
// ...
plugins:[// ...new webpack.DefinePlugin({ // 定义全局变量CONSTANT: JSON.stringify(constant)})],

3.修改package.json

"scripts": {"dev": "cross-env NODE_ENV=development webpack-dev-server","build": "cross-env NODE_ENV=production webpack --config ./webpack.config.js","test": "echo \"Error: no test specified\" && exit 1"},
  • cross-env用来磨平mac和win中的node环境之间的不同,所以我们需要安装一下
npm install cross-env -D
  • NODE_ENV=developmentNODE_ENV=production指定node环境

4.运行及调试

  • 由于修改了webpack.config.js所以需要重新运行npm run dev
  • 在src/main.js后面加上一句测试代码:console.log(CONSTANT);
  • 配置成功打印出来

十、区分开发环境打包跟生产环境打包

在config下新建两个文件

  • webpack.dev.js 开发环境使用
  • webpack.prod.js 生产环境使用
  • webpack.config.js 公用配置

公共配置webpack.config.js

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackplugin = require('html-webpack-plugin');
const webpack = require('webpack');
const constant = require('./config/constant'); // 引入常量文件
module.exports = {entry : './src/main.js',//入口文件output : {//输出文件filename : 'index.js',//输出文件名path :  __dirname+'/public',//输出文件路径// publicPath: "public", // 虚拟目录,自动指向path编译目录,放在内存中,所以在硬盘上是找不到的 默认是:/},module : { // 当执行require或import命令时匹配下面的加载规则rules: [{/*将js或者jsx文件转码成es5*/test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件exclude: /node_modules/,//排除这个文件夹use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},{ // vue文件处理test: /\.vue$/,use: [{loader: 'cache-loader'},{loader: 'thread-loader'},{loader: 'vue-loader',options: {compilerOptions: {preserveWhitespace: false},}},]},// { // 文件资源加载 变成base64会跟下面图片资源处理冲突所以注释了//     test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,//     use: [{//       loader: 'url-loader',//       options: {//           name: '[name].[ext]'//       }//     }]// },{ // 图片资源处理test: /\.(png|jpg|gif|svg)/,use: [{loader: "file-loader",options: {name: '[name].[ext]',outputPath: "public/assets/", // 输出目录limit: 8192,}}]}]},plugins:[new HtmlWebpackplugin({filename: 'index.html', // 打包后的文件名,默认是index.htmltemplate: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板}),new VueLoaderPlugin(),new webpack.DefinePlugin({ // 定义全局变量CONSTANT: JSON.stringify(constant)})],
}

开发环境

  • 不需要压缩代码
  • 需要本地服务和热更新
  • css不需要提取到css文件
  • sourceMap
const merge = require('webpack-merge')
const webpackConfig = require('../webpack.config')
module.exports = merge(webpackConfig, {devtool: 'cheap-module-eval-source-map',mode: 'development',// 指定开发者打包模式devServer: { //node本地服务器host: '127.0.0.1',port: 8010},module : {rules: [{test: /\.(scss|sass)$/,use: [{loader: 'style-loader'},{loader: 'css-loader'},{loader: 'sass-loader',options: {implementation: require('dart-sass')}},{loader: 'postcss-loader',options: {plugins: [require("autoprefixer") /*自动添加前缀*/]}}]},]},
})

生产环境

  • 压缩代码
  • 不需要本地服务和热更新
  • 提取css,压缩css文件
  • sourceMap
  • 构建前清除上一次构建的内容
const path = require('path')
const merge = require('webpack-merge')
const webpack = require('webpack')
const webpackConfig = require('../webpack.config')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = merge(webpackConfig, {mode: 'production',// 指定开发者打包模式压缩js代码devtool: '#source-map',optimization: {splitChunks: {cacheGroups: {vendors: {name: 'chunk-vendors',test: /[\\\/]node_modules[\\\/]/,priority: -10,chunks: 'initial'},common: {name: 'chunk-common',minChunks: 2,priority: -20,chunks: 'initial',reuseExistingChunk: true}}}},module: {rules: [{test: /\.(scss|sass)$/,use: [{loader: MiniCssExtractPlugin.loader},{loader: 'css-loader',options: {importLoaders: 2}},{loader: 'sass-loader',options: {implementation: require('dart-sass')}},{loader: 'postcss-loader',options: {plugins: [require("autoprefixer") /*自动添加前缀*/]}}]},]},plugins: [new MiniCssExtractPlugin({filename: 'css/[name].[contenthash:8].css',chunkFilename: 'css/[name].[contenthash:8].css'}),new OptimizeCssnanoPlugin({sourceMap: true,cssnanoOptions: {preset: ['default',{mergeLonghand: false,cssDeclarationSorter: false}]}}),new CopyWebpackPlugin([{from: path.resolve(__dirname, '../public'),to: path.resolve(__dirname, '../dist')}]),new CleanWebpackPlugin(), // 用于删除上次构建的文件]
})

安装所需依赖

npm i @intervolga/optimize-cssnano-plugin mini-css-extract-plugin clean-webpack-plugin webpack-merge copy-webpack-plugin -D
  • @intervolga/optimize-cssnano-plugin 用于压缩css代码
  • mini-css-extract-plugin 用于提取css到文件中
  • clean-webpack-plugin 用于删除上次构建的文件
  • webpack-merge 合并 webpack配置
  • copy-webpack-plugin 用户拷贝静态资源

图片资源路径名使用
修改src/App.vue

<template><div><div class="App"><img :src="imgUrl1"><div>Hello {{msg}}</div></div><div><router-link to="/page1">go page1</router-link><router-link to="/page2">go page2</router-link></div><div><router-view></router-view></div></div>
</template>
<script>
export default {name: 'App',data() {return {msg: "diyVue",imgUrl1: require('./assets/logo.png'),};}
};
</script>
<style lang="scss" scoped>.App{color:red;}
</style>

这次的操作优化了图片资源的引用,我们执行npm run dev后,在浏览器打开项目,可以看到

优化前这个路径是base64位的,现在变成了一个普通的路径。

总结:

vue-cli是一个封装得很完美的vue脚手架,所以它的适应性很强;但是有些大公司他们的前端项目一般不会直接套用这种脚手架,而是需要结合公司内部的组件一步步搭起一个vue前端项目。
单纯的vue架构是非常简单的,但是结合到node环境和webpack一起用的话,有一些不是太熟悉node、webpack的前端同学就会有些蒙圈。这个案例中,我们主要是搭建好了一个webpack环境,然后将需要的东西一件一件组装起来,虽然不算太完善,但是学会了这种思路的话,我们处理其他前端项目也不难了。

如果帮助到你了,就点赞,哈哈哈,不可能有赞的!

从0到1架构webpack+vue前端项目,你自己搭建过vue开发环境吗相关推荐

  1. Vue启动项目如何区分启动的是开发环境、测试环境、生产环境

    1. vue 中有个概念就是模式,Vue CLI 项目有三个模式: development 模式用于 vue-cli-service serve test 模式用于 vue-cli-service t ...

  2. B站云E办Springboot+vue——前端项目完整版(含源码)

    一.项目简介 项目背景:受疫情的影响,许多企业由线上办公转为线下办公.随着线上办公的人数的增多,线上办公的优点逐步凸显:通过实现工作流程的自动化.节省企业办公费用.实现绿色办公,同时提升办公效率. 项 ...

  3. Vue前端项目【尚品汇】

    Vue前端项目[尚品汇] 1. 说明 2. 对项目创建 3.结构 4. 项目运行起来时,浏览器自动打开 5.关闭ESLint校验功能 5.路由分析 6.路由元信息 7. 路由传参 7.1 路由的跳转方 ...

  4. VUE项目学习(一):搭建VUE前端项目

    VUE项目学习(一):搭建VUE前端项目 1.安装node.js环境 (1)下载node.js,下载地址为:https://nodejs.org/en/ (2)按照默认选项安装node,检查安装版本 ...

  5. vue 前端项目部署阿里云服务器

    vue 前端项目部署阿里云服务器 one 前期准备 two 代码打包 扔服务器 one 前期准备 首先两个软件应该下载(Xftp Xshell),如果有其他类似的软件也可以. 打开xftp,新建一个会 ...

  6. 搭建vue前端框架或微信小程序vue框架步骤

    搭建vue前端框架或微信小程序vue框架步骤 1.下载node.js 下载地址:https://nodejs.org/en/download/ 查看node.npm版本,确保环境正确 node --v ...

  7. cmd搭建vue前端项目详细过程

    cmd 搭建vue前端项目 下载nods.js node.js下载(Windows版本) next 安装完毕! 配置node.js环境变量 进入找到Path进入 这里填你的node.js的安装路径 验 ...

  8. webpack打包前端项目入门

    前言:在开发过程中,利用webpack可以帮我们自动把ES6语法编译成低版本浏览器能解析的JavaScript代码.下面给出webpack打包前端项目入门案例. [终端:进入项目所在目录] 1.初始化 ...

  9. Vue前端项目-Vuex实战使用

    目录 1.创建 vue-cli 脚手架项目 2.安装 vuex 3.将 store 实例注册到 Vue对象 4. store 实例对象 5.将 store 分割成模块化(Module) 6.项目中的模 ...

  10. Vue前端项目自适应布局

    Vue前端项目自适应布局 一.单位尺寸 二.基于rem实现自适应布局 一.单位尺寸 px % vw.vh: 窗口 em: 针对父元素的font-size rem:"root em" ...

最新文章

  1. 有关EUV光刻机,你需要知道这些
  2. Css布局系列-综合应用
  3. 录音文件下载_苹果手机录音常见问题解答
  4. 学生上课考勤系统jsp_基于jsp的学生课堂考勤-JavaEE实现学生课堂考勤 - java项目源码...
  5. kafka 串讲:架构模型、角色功能梳理
  6. 【转载】ADS分散加载文件使用总结(lpc23xx)
  7. (135)FPGA面试题-介绍FPGA的速度等级与温度等级
  8. “不差钱”华为刷屏 拟募资60亿!
  9. 软件开发从需求分析开始
  10. 计算机系统 cpu课程,计算机操作系统
  11. Linux module 添加到bashrc 和临时ifort编译器 以及python2和3的配置
  12. STM32f103正点原子小白 FLYMcu串口
  13. 电力-104规约实际测试1
  14. matlab 保存不了文件,关于matlab文件无法保存的原因(转)
  15. 多元统计分析-联合分析
  16. 列线图计算每个患者得分,并生成Roc曲线。
  17. 高通 mdm9607编译以及audio框架
  18. Cadence制作flash焊盘时找不到
  19. uni保存canvas图片_UniApp 用canvas生成图片保存本地
  20. 常见的head内标签

热门文章

  1. 网络安全产品之堡垒机应用于金融行业案例讲解
  2. [Luogu2359] 三素数数
  3. 深入理解 Objective-C:Category
  4. 【大学四年自学Java的学习路线】写了一个月
  5. python用turtle画国旗
  6. 赛迪顾问股价波动侧面观
  7. Linux——配置时间以及时间同步
  8. 警示!一幅漫画揭示了项目研发过程中存在的问题
  9. 垃圾分类助手用户协议
  10. 如何用Keras打造出“风格迁移”的AI艺术作品