这篇文章会告诉你

它不会告诉你

  • 什么是vue,webpack

在创建vue项目时,官方推荐使用vue-cli这个命令行工具。原文是这么说的

# 全局安装 vue-cli
$ npm install --global vue-cli
# 创建一个基于 webpack 模板的新项目
$ vue init webpack my-project
# 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev

执行npm run dev 会运行webpack。大致会编译vue格式文件,热加载,eslint语法检测等功能。开发时过程带给我们非常省时省力的体验。

下面讲下当执行npm run dev后都发生了什么。

首先当通过vue-cli创建vue项目。执行的vue init webpack my-project

实际拷贝的是 https://github.com/vuejs-templates/webpack 中template提供的配置文件模版。他给我们提供了vue项目所需的架子并整合了webpack相关配置。

我们熟悉的build, src, config等目录都里面。

通过 package.json 可以看出有四个命令。

开发时要运行 npm run dev 或 npm run start 或 npm start

线上及生产环境要运行 npm run build

检测JS语法运行 npm run lint

  "scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src"
},

npm run dev实际执行的就是 node build/dev-server.js

打开dev-server.js,第一行是 require('./check-versions')()  先分析这个文件

check-versions.js

大致就是将当前运行的node和npm环境与package.json中的engines中node和npm要求的最低版本进行对比,看是否满足需求。

// 不错的node模块,使输出内容带前景色和背景色
var chalk = require('chalk')
// 语义化版本,详见http://semver.org/lang/zh-CN/
// https://www.npmjs.com/package/semver
var semver = require('semver')
var packageConfig = require('../package.json')
// 顾名思义,提供了一些和shell命令名字功能都一样的方法
var shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
} var versionRequirements = [
{
name: 'node',
// semver.clean(' =v1.2.3 ') => '1.2.3'
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
] if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
} module.exports = function () {
var warnings = []
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
} if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}

打开package.json,你可以将

"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},

改为

"engines": {
"node": ">= 4.0.0",
"npm": ">= 6.0.0"
},

然后运行 npm run dev 就会输出类似的错误

config/index.js

接着是var config = require('../config')

这里定义了一些开发环境和生产环境中不同的环境参数以及供后面的webpack配置文件使用的参数。

举个例子,为什么运行npm run dev会自动打开浏览器并且地址端口是8080。就是在这里面定义的。

更详细的参见:

https://github.com/vuejs-templates/webpack/blob/develop/docs/env.md

开发过程中可能需要调用后端的接口,如果要设置代理。

参见:

https://github.com/vuejs-templates/webpack/blob/develop/docs/proxy.md

本质上用到一个叫 http-proxy-middleware http代理中间件的node模块

// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path') module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}

env.js

dev.env.js 和 prod.env.js 里面放一些配置变量

比如我添加了一个KEY_ID

var merge = require('webpack-merge')
var prodEnv = require('./prod.env') module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
KEY_ID: '123456'
})

在vue文件里就可以用process.env.KEY_ID 输出 123456

为什么? 原理是用到了webpack提供的 DefinePlugin 插件

  plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),

注意字符串要写两个引号。

回到dev-server.js,接着分析webpack配置文件。这类的文章很多了,简要分析下

webpack.dev.conf

// 工具方法
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
// webpack官方提供的一个webpack配置文件合并工具
var merge = require('webpack-merge')
// 开发时和发布时公用的配置文件信息
var baseWebpackConfig = require('./webpack.base.conf')
// 一个webpack插件,生成入口html文件,最强大的功能是动态自动插入webpack生成的css和js资源文件
// 一般的单页面应用只有一个主html文件比如index.html,webpack打包生成js和css文件后,
// 我们当然可以在手动写标签引入这些资源文件,但有时候生成后的文件带有hash。如app-3d31retr.js。这时需要自动引入,并替换html。
var HtmlWebpackPlugin = require('html-webpack-plugin')
// 不解释,自行去github查文档
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') // add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
}) module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// cheap-module-eval-source-map is faster for development
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new FriendlyErrorsPlugin()
]
})

webpack.base.conf

主要讲下resolve部分,webpack把各种类型资源的文件当做module来处理,并通过相应的loader编译成js可运行的代码。

在vueLoaderConfig里已经定义了各种style loader了

  resolve: {
// 导入文件自动补全文件后缀
// 比如 src/index.js 中的 import App from './App'
// 完整的是import App from './App.vue'
extensions: ['.js', '.vue', '.json'],
// 别名映射,引入模块中可缩短字符串长度
// 如 import {playMode} from 'common/js/config' 可能实际是
// import {playMode} from '../../common/js/config'
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
'common': resolve('src/common'),
'components': resolve('src/components'),
'base': resolve('src/base'),
'api': resolve('src/api')
}
},
module: {
rules: [
// {
// test: /\.(js|vue)$/,
// loader: 'eslint-loader',
// enforce: 'pre',
// include: [resolve('src'), resolve('test')],
// options: {
// // 友好提供eslint未通过原因及链接
// formatter: require('eslint-friendly-formatter')
// }
// },
{
test: /\.vue$/,
// https://vue-loader.vuejs.org/zh-cn/configurations/pre-processors.html
loader: 'vue-loader',
// 最终结果类似,
/*
options: {
loaders: {
css: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
}],
postcss: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
}],
less: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
},
{
loader: 'less-loader',
options: {
sourceMap: false
}
}],
sass: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
indentedSyntax: true,
sourceMap: false
}
}],
scss: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
sourceMap: false
}
}],
stylus: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: false
}
}],
styl: ['vue-style-loader', {
loader: 'css-loader',
options: {
minimize: false,
sourceMap: false
}
},
{
loader: 'stylus-loader',
options: {
sourceMap: false
}
}]
}
}
*/
options: vueLoaderConfig
},

为什么在vue中的style中定义 lang="stylus" 或  lang="less"  就能直接写相应的预处理语言啦。因为上面的webpack.base中已经把各种样式loader都定义好啦

为什么可以在vue类型类型里用 <template>, <script> 和 <style>。这是vue-loader的功劳。当然也离不开webpack。

详见:https://vue-loader.vuejs.org/zh-cn/start/spec.html

dev-server.js

// 检测是否满足版本需要
require('./check-versions')()
// 引入外层config中的index.js,分为运行时和开发时的变量信息
// 我们可以自己添加一些变量
var config = require('../config')
if (!process.env.NODE_ENV) {
// 最终变成 process.env.NODE_ENV = JSON.parse('"development"')
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
} // 第三方模块。可调用系统默认的程序打开图片,地址等,如opn('http://localhost:8080'); open('./demo.jpg')
var opn = require('opn')
// node内置的核心模块
var path = require('path')
// node框架,在这里用来启动webserver
var express = require('express')
// 不解释,核心编译工具
// 官方文档中不推荐全局安装webpack,然后执行全局变量的方式
// 这里在nodejs里引入webpack,用提供的api来配置并启动
var webpack = require('webpack')
// http代理中间件,可转发api等
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')

简单说

开发用的webpack配置文件是 webpack.dev.conf.js + webpack.base.conf.js合并后的结果

主要实现热加载,友好的错误输出,方便调试等功能

生产环境用到的是webpack.prod.conf.js + webpack.base.conf.js合并后的结果

主要实现打包压缩css和js,不输出警告和错误

参见:

https://vue-loader.vuejs.org/zh-cn/workflow/production.html

总结:多看官方文档,多上github查资料。

https://github.com/vuejs-templates/webpack/blob/develop/docs/README.md

https://vue-loader.vuejs.org/zh-cn/

https://cn.vuejs.org/v2/guide/deployment.html

大致就是这些,有空再更。由于本人知识有限,文章有什么不对的,还请斧正~~~

vue-webpack-boilerplate分析的更多相关文章

  1. 一字一句的搞懂vue-cli之vue webpack template配置

    webpack--神一样的存在.无论写了多少次,再次相见,仍是初见.有的时候开发vue项目,对尤大的vue-cli感激涕零.但是,但是,但是...不是自己的东西,真的很不想折腾.所以,我们就得深入内部 ...

  2. 【原创】从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(二)

    摘要:上篇文章说到了如何新建工程,并启动一个最简单的Electron应用.“跑起来”了Electron,那就接着把Vue“跑起来”吧.有一点需要说明的是,webpack是贯穿这个系列始终的,我也是本着 ...

  3. Vue源码分析(一) : new Vue() 做了什么

    Vue源码分析(一) : new Vue() 做了什么 author: @TiffanysBear 在了解new Vue做了什么之前,我们先对Vue源码做一些基础的了解,如果你已经对基础的源码目录设计 ...

  4. vue+webpack实践

    最近使用了vue来做SPA应用,记一波学习笔记. 使用vue+webpack实现前端模块化. vuejs——轻量.学习成本低.双向绑定.无dom的操作.组件的形式编写 推荐官方文档 vue.js官方文 ...

  5. windows环境下搭建vue+webpack的开发环境

    前段时间一直在断断续续的看vue的官方文档,后来就慢慢的学习搭建vue的开发环境,已经有将近两周了,每到最后一步的时候就会报错,搞的我好郁闷,搁置了好几天,今天又接着搞vue的开发环境,终于成功了.我 ...

  6. Vue + Webpack + Vue-loader 1

    Vue + Webpack + Vue-loader 原文地址:https://lvyongbo.gitbooks.io/vue-loader/content/ Vue-loader 是什么? vue ...

  7. Vue实战Vue-cli项目构建(Vue+webpack系列之一)

    用Vue比较长一段时间了,大大小小做了一些项目,最近想总结一下知识点,出一个Vue+webpack系列,先从项目构建说起--vue-cli. 由于是Vue+webpack这里就不赘述git那些东西,默 ...

  8. 从零开始:一个正式的vue+webpack项目的目录结构是怎么形成的

    如何从零开始一个vue+webpack前端工程工作流的搭建,首先我们先从项目的目录结构入手.一个持续可发展,不断加入新功能,方便后期维护的目录结构究竟是长什么样子的?接下来闰土大叔带你们一起手摸手学起 ...

  9. 前端Vue 源码分析-逻辑层

    Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...

  10. vue学习:vue+webpack的快速使用指南(新手向)

    一.vue有两种使用方式: 1.下载vue.js <script src="vue.js"></script> 2.使用npm npm install vu ...

随机推荐

  1. 常用颜色RGB、灰度值

    128/0/0       深红         255/0/0       红           255/0/255     粉红        255/153/204 玫瑰红       153 ...

  2. 移动端https抓包那些事--进阶篇

    上一次和大家介绍了手机端https抓包的初级篇,即在手机未root或者未越狱的情况下如何抓取https流量,但是当时分析应用时会发现,好多应用的https的流量还是无法抓取到,这是为什么呢? 主要原因 ...

  3. OpenOfice将offic转为pdf并且在web显示

    1.将office首先要安装OpenOfice,傻瓜式安装就好了,之后可以使用下列代码将word转为pdf.这个需要导入jodconverter-2.2.2里的 ja r包 import java.i ...

  4. ios UIButton改背景

    以下orangeButton.png与orangeButtonHighlight.png分别用于按钮平常状态和被点击时的状态: UIImage *buttonImage = [[UIImage ima ...

  5. Linux操作系统-命令-netstat

    # 之前已经写过了3篇与"性能测试"有关系的Linux命令,它们分别是free.top.vmstat # 接下来还需要把另外2个命令也写下来:netstat和iostat 最近认真地读了1篇关于"定位 ...

  6. 浅析MySQL中的Index Condition Pushdown (ICP 索引条件下推)和Multi-Range Read(MRR 索引多范围查找)查询优化

    本文出处:http://www.cnblogs.com/wy123/p/7374078.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...

  7. Windows 程序注册成服务的方法

    Windows 程序注册成服务的方法 将windows 程序注册成服务这个是很多后台程序需要实现的功能,注册成服务后,你的程序就可以像windows 服务一样随系统启动,并且隐藏你的控制台界面.下面介 ...

  8. 表空间移动(transporting tablespaces)

    --表空间移动(transporting tablespaces) --------------------------------------2014/01/15   1. 表空间传输步骤简介.   ...

  9. 轻量级ORM框架 QX_Frame.Bantina(一、框架简介)

    轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...

  10. js中的访问器属性中的getter和setter函数实现数据双向绑定

    嗯,之前在读js红宝书的时候,在对象那一章有介绍属性类型.第一种数据类型指的是数据属性,第二种是访问器属性.在初识vue的时候,其双向数据绑定也是基于访问器属性中的getter和setter函数原理来 ...