一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)


Posted in Javascript onJanuary 08, 2018

Vue作为前端三大框架之一截至到目前在github上以收获44,873颗星,足以说明其以悄然成为主流。16年10月Vue发布了2.x版本,经过了一段时间的摸索和看官方的教程和api,才了解到2.0版本在1.0版本的基础上做了好多调整,废弃了好多api。

本文将详细介绍关于利用webpack搭一个vue脚手架的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

一.适用人群

   1.对webpack知识有一定了解但不熟悉的同学.

    2.女同学!!!(233333....)

二.目的

在自己对webpack有进一步了解的同时,也希望能帮到一些刚接触webpack的同学.

脚手架已放上github,不想听我??碌耐?Э梢灾苯尤?ownload或clone下来看哦.

脚手架里都有详细注释!

源码:https://github.com/webfansplz/xc-cli.git  (本地下载)

觉得有帮助到你的同学给个star哈,也算是对我的一种支持!

三.脚手架结构

├── build  构建服务和webpack配置
 |—— build.js webpack打包服务
 |—— webpack.base.conf.js webpack基本通用配置
 |—— webpack.dev.conf.js webpack开发环境配置
 |—— webpack.prod.conf.js webpack生产环境配置
├── config  构建项目不同环境的配置
├── public  项目打包文件存放目录
├── index.html  项目入口文件
├── package.json 项目配置文件
├── static  静态资源
├── .babelrc  babel配置文件
├── .gitignore  git忽略文件
├── postcss.config.js postcss配置文件
├── src  项目目录
 |—— page  页面组件目录
 |—— router  vue路由配置
 |—— store  vuex配置
 |—— App.vue  vue实例入口
 |—— main.js  项目构建入口

四.配置npm scripts

4.1 生成package.json文件,配置npm scripts.

4.1.1 使用 npm init 命令,生成一个package.json文件!

npm init

4.1.2 全局安装webpack和webpack-dev-server

npm install webpack webpack-dev-server -g

4.1.3 在项目目录下安装webpack和webpack-dev-server

npm install webpack webpack-dev-server -D

4.1.4 进入package.json配置npm scripts命令

"scripts": {
 "dev": "webpack-dev-server --config build/webpack.dev.conf.js",
 "start": "npm run dev",
 "build": "node build/build.js"
 }

  通过配置以上命令:

  我们可以通过npm start/npm run dev在本地进行开发,

  scripts.dev命令解读:

  通过webpack-dev-server命令 启动build文件夹下webpack.dev.conf.js。

  也可以通过npm run build 打包项目文件进行线上部署.

  scripts.build命令解读:

  通过node命令构建build文件夹下的build.js。

  命令的配置可以根据自己脚手架的配置文件位置和名称不同修改哦!

五.构建脚手架目录

同学们可以通过自己的习惯和喜爱搭建自己的脚手架目录,下面讲解以上面脚手架结构为准!

六.构建config/config.js

6.1 该文件主要用来配置构建开发环境和生产环境差异化的参数.

6.2

const _path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
//vue-loader基本配置
const baseVueLoaderConf = {
 //引入postcss插件
 postcss: {
 config: {
 path: _path.resolve("../")
 }
 },
 //转为require调用,让webpack处理目标资源!
 transformToRequire: {
 video: "src",
 source: "src",
 img: "src",
 image: "xlink:href"
 }
};
//vue-loader 开发环境配置
const devVueLoaderConf = Object.assign({}, baseVueLoaderConf, {
 //loaders
 loaders: {
 css: ["vue-style-loader", "css-loader"],
 less: ["vue-style-loader", "css-loader", "postcss-loader", "less-loader"]
 },
 cssSourceMap: true
});
//vue-loader 生产环境配置
const buildVueLoaderConf = Object.assign({}, baseVueLoaderConf, {
 //loaders
 loaders: ExtractTextPlugin.extract({
 use: ["css-loader", "postcss-loader", "less-loader"],
 fallback: "vue-style-loader"
 }),
 cssSourceMap: false
});
//开发/生产环境 配置参数!
module.exports = {
 dev: {
 publicPath: "/",
 devtoolType: "cheap-module-eval-source-map",
 vueloaderConf: devVueLoaderConf,
 host: "localhost",
 port: "1234",
 proxyTable: {}
 },
 build: {
 publicPath: "/",
 devtoolType: "source-map",
 vueloaderConf: buildVueLoaderConf,
 staticPath: "static"
 }
};

七.构建build/webpack.base.conf.js

7.1 此文件主要是webpack开发环境和生成环境的通用配置.

7.2

"use strict";
//引入node path路径模块
const path = require("path");
//引入webpack生产环境配置参数
const prodConfig = require("../config").build;
//拼接路径
function resolve(track) {
 return path.join(__dirname, "..", track);
}
//资源路径
function assetsPath(_path) {
 return path.join(prodConfig.staticPath, _path);
}
//webpack 基本设置
module.exports = {
 //项目入口文件->webpack从此处开始构建!
 entry: path.resolve(__dirname, "../src/main.js"),
 //配置模块如何被解析
 resolve: {
 //自动解析文件扩展名(补全文件后缀)(从左->右)
 // import hello from './hello' (!hello.js? -> !hello.vue? -> !hello.json)
 extensions: [".js", ".vue", ".json"],
 //配置别名映射
 alias: {
 // import Vue from 'vue/dist/vue.esm.js'可以写成 import Vue from 'vue'
 // 键后加上$,表示精准匹配!
 vue$: "vue/dist/vue.esm.js",
 "@": resolve("src"),
 utils: resolve("src/utils"),
 components: resolve("src/components"),
 public: resolve("public")
 }
 },
 module: {
 //处理模块的规则(可在此处使用不同的loader来处理模块!)
 rules: [
 //使用babel-loader来处理src下面的所有js文件,具体babel配置在.babelrc,主要是用来转义es6
 {
 test: /\.js$/,
 use: {
 loader: "babel-loader"
 },
 include: resolve("src")
 },
 //使用url-loader(file-loader的一个再封装)对引入的图片进行编码,此处可将小于8192字节(8kb)的图片转为DataURL(base64),
 //大于limit字节的会调用file-loader进行处理!
 //图片一般发布后都是长缓存,故此处文件名加入hash做版本区分!
 {
 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
 loader: "url-loader",
 options: {
 limit: 8192,
 name: assetsPath("img/[name].[hash:8].[ext]")
 }
 }
 ]
 }
};

八.构建 build/webpack.dev.conf.js

8.1 该文件主要用于构建开发环境

8.2

"use strict";
//引入node path路径模块
const path = require("path");
//引入webpack
const webpack = require("webpack");
//引入webpack开发环境配置参数
const devConfig = require("../config").dev;
//引入webpack基本配置
const baseConf = require("./webpack.base.conf");
//一个webpack配置合并模块,可简单的理解为与Object.assign()功能类似!
const merge = require("webpack-merge");
//一个创建html入口文件的webpack插件!
const HtmlWebpackPlugin = require("html-webpack-plugin");
//一个编译提示的webpack插件!
const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin");
//发送系统通知的一个node模块!
const notifier = require("node-notifier");
//将webpack基本配置与开发环境配置合并!
const devConf = merge(baseConf, {
 //项目出口,webpack-dev-server 生成的包并没有写入硬盘,而是放在内存中!
 output: {
 //文件名
 filename: "[name].js",
 //html引用资源路径,在dev-server中,引用的是内存中文件!
 publicPath: devConfig.publicPath
 },
 //生成sourceMaps(方便调试)
 devtool: devConfig.devtoolType,
 //
 //启动一个express服务器,使我们可以在本地进行开发!!!
 devServer: {
 //HMR控制台log等级
 clientLogLevel: "warning",
 // 热加载
 hot: true,
 //自动刷新
 inline: true,
 //自动打开浏览器
 open: true,
 //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
 historyApiFallback: true,
 //主机名
 host: devConfig.host,
 //端口号
 port: devConfig.port,
 //配置反向代理解决跨域
 proxy: devConfig.proxyTable,
 //为你的代码进行压缩。加快开发流程和优化的作用
 compress: true,
 // 在浏览器上全屏显示编译的errors或warnings。
 overlay: {
 errors: true,
 warnings: false
 },
 // 终端输出的只有初始启动信息。 webpack 的警告和错误是不输出到终端的
 quiet: true
 },
 module: {
 //处理模块的规则(可在此处使用不同的loader来处理模块!)
 rules: [
 //使用vue-loader处理以vue结尾的文件!
 {
 test: /\.vue$/,
 loader: "vue-loader",
 options: devConfig.vueloaderConf
 },
 //使用vue-style-loader!css-loader!postcss-loader处理以css结尾的文件!
 {
 test: /\.css$/,
 use: [
 "vue-style-loader",
 {
 loader: "css-loader",
 options: {
 sourceMap: true
 }
 },
 {
 loader: "postcss-loader",
 options: {
 sourceMap: true
 }
 }
 ]
 },
 //使用vue-style-loader!css-loader!postcss-loader处理以less结尾的文件!
 {
 test: /\.less$/,
 use: [
 "vue-style-loader",
 {
 loader: "css-loader",
 options: {
 sourceMap: true
 }
 },
 {
 loader: "less-loader",
 options: {
 sourceMap: true
 }
 },
 {
 loader: "postcss-loader",
 options: {
 sourceMap: true
 }
 }
 ]
 }
 ]
 },
 plugins: [
 //开启HMR(热替换功能,替换更新部分,不重载页面!)
 new webpack.HotModuleReplacementPlugin(),
 //显示模块相对路径
 new webpack.NamedModulesPlugin(),
 //编译出错时,该插件可跳过输出,确保输出资源不会包含错误!
 // new webpack.NoEmitOnErrorsPlugin(),
 //配置html入口信息
 new HtmlWebpackPlugin({
 title: "hello,xc-cli!",
 filename: "index.html",
 template: "index.html",
 //js资源插入位置,true表示插入到body元素底部
 inject: true
 }),
 //编译提示插件
 new FriendlyErrorsPlugin({
 //编译成功提示!
 compilationSuccessInfo: {
 messages: [
 `Your application is running here: http://${devConfig.host}:${devConfig.port}`
 ]
 },
 //编译出错!
 onErrors: function(severity, errors) {
 if (severity !== "error") {
 return;
 }
 const error = errors[0];
 const filename = error.file.split("!").pop();
 //编译出错时,右下角弹出错误提示!
 notifier.notify({
 title: "xc-cli",
 message: severity + ": " + error.name,
 subtitle: filename || "",
 icon: path.join(__dirname, "xc-cli.png")
 });
 }
 })
 ]
});
module.exports = devConf;

8.3 通过创建以上文件,并下载相应的依赖和创建项目入口,我们就可以通过npm run dev在本地开发vue项目啦!!!

九.创建 build/webpack.prod.conf.js

9.1 此文件主要用于构建生产环境的配置.

9.2

"use strict";
//引入node path路径模块
const path = require("path");
//引入webpack
const webpack = require("webpack");
//一个webpack配置合并模块,可简单的理解为与Object.assign()功能类似!
const merge = require("webpack-merge");
//引入webpack生产环境配置参数
const prodConfig = require("../config").build;
//引入webpack基本配置
const baseConf = require("./webpack.base.conf");
//一个创建html入口文件的webpack插件!
const HtmlWebpackPlugin = require("html-webpack-plugin");
//一个抽离出css的webpack插件!
const ExtractTextPlugin = require("extract-text-webpack-plugin");
//一个压缩css的webpack插件!
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
//一个拷贝文件的webpack插件!
const CopyWebpackPlugin = require("copy-webpack-plugin");

//资源路径
function assetsPath(_path) {
 return path.join(prodConfig.staticPath, _path);
}
//将webpack基本配置与生产环境配置合并!
const prodConf = merge(baseConf, {
 //项目出口配置
 output: {
 //Build后所有文件存放的位置
 path: path.resolve(__dirname, "../public"),
 //html引用资源路径,可在此配置cdn引用地址!
 publicPath: prodConfig.publicPath,
 //文件名
 filename: assetsPath("js/[name].[chunkhash].js"),
 //用于打包require.ensure(代码分割)方法中引入的模块
 chunkFilename: assetsPath("js/[name].[chunkhash].js")
 },
 //生成sourceMaps(方便调试)
 devtool: prodConfig.devtoolType,
 module: {
 //处理模块的规则(可在此处使用不同的loader来处理模块!)
 rules: [
 //使用vue-loader处理以vue结尾的文件!
 {
 test: /\.vue$/,
 loader: "vue-loader",
 options: prodConfig.vueloaderConf
 },
 {
 test: /\.css$/,
 use: ExtractTextPlugin.extract({
  use: ["css-loader", "postcss-loader"],
  fallback: "vue-style-loader"
 })
 },
 {
 test: /\.less$/,
 use: ExtractTextPlugin.extract({
  use: ["css-loader", "less-loader", "postcss-loader"],
  fallback: "vue-style-loader"
 })
 }
 ]
 },
 plugins: [
 //每个chunk头部添加hey,xc-cli!
 new webpack.BannerPlugin("hey,xc-cli"),
 //压缩js
 new webpack.optimize.UglifyJsPlugin({
 parallel: true,
 compress: {
 warnings: false
 }
 }),
 //分离入口引用的css,不内嵌到js bundle中!
 new ExtractTextPlugin({
 filename: assetsPath("css/[name].[contenthash].css"),
 allChunks: false
 }),
 //压缩css
 new OptimizeCSSPlugin(),
 //根据模块相对路径生成四位数hash值作为模块id
 new webpack.HashedModuleIdsPlugin(),
 //作用域提升,提升代码在浏览器执行速度
 new webpack.optimize.ModuleConcatenationPlugin(),
 //抽离公共模块,合成一个chunk,在最开始加载一次,便缓存使用,用于提升速度!
 // 1. 第三方库chunk
 new webpack.optimize.CommonsChunkPlugin({
 name: "vendor",
 minChunks: function(module) {
 //在node_modules的js文件!
 return (
  module.resource &&
  /\.js$/.test(module.resource) &&
  module.resource.indexOf(path.join(__dirname, "../node_modules")) === 0
 );
 }
 }),
 // 2. 缓存chunk
 new webpack.optimize.CommonsChunkPlugin({
 name: "manifest",
 minChunks: Infinity
 }),
 // 3.异步 公共chunk
 new webpack.optimize.CommonsChunkPlugin({
 name: "app",
 children: true,
 // (选择所有被选 chunks 的子 chunks)
 async: true,
 // (创建一个异步 公共chunk)
 minChunks: 3
 // (在提取之前需要至少三个子 chunk 共享这个模块)
 }),
 //将整个文件复制到构建输出指定目录下
 new CopyWebpackPlugin([
 {
 from: path.resolve(__dirname, "../static"),
 to: prodConfig.staticPath,
 ignore: [".*"]
 }
 ]),
 //生成html
 new HtmlWebpackPlugin({
 filename: path.resolve(__dirname, "../public/index.html"),
 template: "index.html",
 favicon: path.resolve(__dirname, "../favicon.ico"),
 //js资源插入位置,true表示插入到body元素底部
 inject: true,
 //压缩配置
 minify: {
 //删除Html注释
 removeComments: true,
 //去除空格
 collapseWhitespace: true,
 //去除属性引号
 removeAttributeQuotes: true
 },
 //根据依赖引入chunk
 chunksSortMode: "dependency"
 })
 ]
});
module.exports = prodConf;

十. 创建 build/build.js

10.1 此文件是项目打包服务,用来构建一个全量压缩包

10.2

"use strict";
//node for loading
const ora = require("ora");
// rm-rf for node
const rm = require("rimraf");
//console for node
const chalk = require("chalk");
//path for node
const path = require("path");
//webpack
const webpack = require("webpack");
//webpack production setting
const config = require("./webpack.prod.conf");
//指定删除的文件
const rmFile = path.resolve(__dirname, "../public/static");
//build start loading
const spinner = ora("building for production...");
spinner.start();
//构建全量压缩包!
rm(rmFile, function(err) {
 if (err) throw err;
 webpack(config, function(err, stats) {
 spinner.stop();
 if (err) throw err;
 process.stdout.write(
 stats.toString({
 colors: true,
 modules: false,
 children: false,
 chunks: false,
 chunkModules: false
 }) + "\n\n"
 );
 if (stats.hasErrors()) {
 console.log(chalk.red(" Build failed with errors.\n"));
 process.exit(1);
 }
 console.log(chalk.cyan(" Build complete.\n"));
 console.log(
 chalk.yellow(
 " Tip: built files are meant to be served over an HTTP server.\n" +
  " Opening index.html over file:// won't work.\n"
 )
 );
 });
});

10.3 创建好以上文件 我们就可以通过npm run build来打包我们的项目文件并部署上线啦。

十一.大功告成!

通过以上步骤,一个spa版的vue脚手架就大功告成啦!

如果对一些细节不懂的可以留言或者上我的github查看

地址:https://github.com/webfansplz/xc-cli.git  (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
UserData用法总结 lanyu出品
Jul 01 Javascript
悄悄用脚本检查你访问过哪些网站的代码
Dec 04 Javascript
Firefox中autocomplete="off" 设置不起作用Bug的解决方法
Mar 25 Javascript
js实现对table动态添加、删除和更新的方法
Feb 10 Javascript
JS仿Windows开机启动Loading进度条的方法
Feb 26 Javascript
JQuery标签页效果的两个实例讲解(4)
Sep 17 Javascript
Bootstrap每天必学之栅格系统(布局)
Nov 25 Javascript
JavaScript电子时钟倒计时
Jan 09 Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 Javascript
bootstrap模态框弹出和隐藏,动态改变中间内容的实例
Aug 10 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
Sep 03 Javascript
angularJs中$scope数据序列化的实例
Sep 30 Javascript
深入理解 webpack 文件打包机制(小结)
Jan 08 #Javascript
webpack构建的详细流程探底
Jan 08 #Javascript
详解ES6中的代理模式——Proxy
Jan 08 #Javascript
Vue v2.4中新增的$attrs及$listeners属性使用教程
Jan 08 #Javascript
实例解析ES6 Proxy使用场景介绍
Jan 08 #Javascript
详解weex默认webpack.config.js改造
Jan 08 #Javascript
关于vue单文件中引用路径的处理方法
Jan 08 #Javascript
You might like
jquery自定义类似$.ajax()的方法实现代码
2013/08/13 Javascript
Ext GridPanel加载完数据后进行操作示例代码
2014/06/17 Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
2014/11/04 Javascript
node.js中的events.emitter.removeListener方法使用说明
2014/12/10 Javascript
jquery隔行换色效果实现方法
2015/01/15 Javascript
jQuery实现悬浮在右上角的网页客服效果代码
2015/10/24 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
2016/06/02 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
浅谈js原生拖放
2016/11/21 Javascript
详解jQuery中的事件
2016/12/14 Javascript
原生js实现下拉框功能(支持键盘事件)
2017/01/13 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
2017/07/17 Javascript
十分钟带你快速了解React16新特性
2017/11/10 Javascript
微信小程序中换行空格(多个空格)写法详解
2018/07/10 Javascript
Javascript读写cookie的实例源码
2019/03/16 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
node.js使用zlib模块进行数据压缩和解压操作示例
2020/02/12 Javascript
Python实现的检测网站挂马程序
2014/11/30 Python
python实现判断一个字符串是否是合法IP地址的示例
2018/06/04 Python
python使用pipeline批量读写redis的方法
2019/02/18 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
机械设计专业应届生求职信
2013/11/21 职场文书
化工专业推荐信范文
2013/11/28 职场文书
团员个人的自我评价
2013/12/02 职场文书
清明节扫墓活动方案
2014/03/02 职场文书
新品发布会主持词
2014/04/02 职场文书
2014年向国旗敬礼活动方案
2014/09/27 职场文书
留学推荐信英文范文
2015/03/26 职场文书
2015国庆节放假通知范文
2015/07/30 职场文书
财务人员入职担保书
2015/09/22 职场文书
跟班学习心得体会(共6篇)
2016/01/23 职场文书
pytorch--之halfTensor的使用详解
2021/05/24 Python
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android
SpringRetry重试框架的具体使用
2021/07/25 Java/Android
一些让Python代码简洁的实用技巧总结
2021/08/23 Python
Android自定义ScrollView实现阻尼回弹
2022/04/01 Java/Android