vue-cli 入门

如果你现在正在使用Vue.js,当你构建一个原型的时候,你所需要做的通常就是通过<script>把Vue.js引入进来,然后就完事了。但是真实情况往往不是这样的。当我们真正开发一个应用的时候,我们不可避免的会用到一大堆的工具,模块化、预处理器、热模块加载、代码校验和测试。这些工具对于一个需要长期维护的大型应用是必须的,但是项目初始化将会是让人痛苦的事情。这就是为什么我们做了vue-cli,让一个简单的命令行工具来帮助你快速的构建一个拥有强大构建能力的Vue.js项目。

安装运行

# 安装vue-cli,npm全局安装
npm install -g vue-cli
# 使用vue-cli初始化项目
vue init webpack my-project-vue

这个命令会从https://github.com/vuejs-temp...获取webpack的模板,并且放到my-project-vue下
详细参考:[](https://github.com/vuejs/vue-...

执行过程如下:

vue init webpack my-project-vueThis will install Vue 2.x version of the template.For Vue 1.x use: vue init webpack#1.0 my-project-vue# 这些都是提示可选的,按需要选择即可,都是一些很有名的js工具,因为测试学习,我全选了
? Project name my-project-vue
? Project description A Vue.js project
? Author yuanyuanyuan
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? Yesvue-cli · Generated "my-project-vue".To get started:cd my-project-vuenpm installnpm run devDocumentation can be found at https://vuejs-templates.github.io/webpack

vuejs-templates/webpack下载和配置好之后,就需要使用npm将相关的依赖和模块进行下载安装

# 进入到目录
cd my-project-vuels
README.md    config       package.json static
build        index.html   src          test

因为vue 初始化的时候也把package.json生成了,npm 可以通过这个json进行模块和依赖安装

# 安装依赖
npm install  //安装package.json里的所有模块依赖

觉得慢,可以修改淘宝源:npm config set registry https://registry.npm.taobao.org

# 开始运行
npm run devDONE  Compiled successfully in 6456ms> Listening at http://localhost:8080

可能会遇到缺少包导致打开页面出现404错误,可以根据包提示安装包
sudo npm install --save strip-ansi ansi-html html-entities
-save和save-dev可以直接将包添加到package.json文件中

至此完成安装并运行,并且可以在浏览器查看到效果:

Welcome to Your Vue.js App

理解原理

本文档主要使用vue-webpack-boilerplate模板来理解,根据官方解释:

webpack - A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.
全功能的webpack + vue-loader模板,并且配置好热更新等功能

npm run dev 这个命令会执行一个dev服务器本地监听,可以热更新

npm run dev: first-in-class development experience.* Webpack + vue-loader for single file Vue components.
* State preserving hot-reload
* State preserving compilation error overlay
* Lint-on-save with ESLint
* Source maps

npm run build 会创建生产环境的配置,会生成合并的文件

npm run build: Production ready build.* JavaScript minified with UglifyJS.
* HTML minified with html-minifier.
* CSS across all components extracted into a single file and minified with cssnano.
* All static assets compiled with version hashes for efficient long-term caching, and a production index.html is auto-generated with proper URLs to these generated assets.
* Use npm run build --reportto build with bundle size analytics.

vue-webpack-boilerplate模板的目录架构大致如下:

.
|-- build                            // 项目构建(webpack)相关代码
|   |-- build.js                     // 生产环境构建代码
|   |-- check-version.js             // 检查node、npm等版本
|   |-- dev-client.js                // 热重载相关
|   |-- dev-server.js                // 构建本地服务器
|   |-- utils.js                     // 构建工具相关
|   |-- webpack.base.conf.js         // webpack基础配置
|   |-- webpack.dev.conf.js          // webpack开发环境配置
|   |-- webpack.prod.conf.js         // webpack生产环境配置
|-- config                           // 项目开发环境配置
|   |-- dev.env.js                   // 开发环境变量
|   |-- index.js                     // 项目一些配置变量
|   |-- prod.env.js                  // 生产环境变量
|   |-- test.env.js                  // 测试环境变量
|-- src                              // 源码目录
|   |-- components                     // vue公共组件
|   |-- store                          // vuex的状态管理
|   |-- App.vue                        // 页面入口文件
|   |-- main.js                        // 程序入口文件,加载各种公共组件
|-- static                           // 静态文件,比如一些图片,json数据等
|   |-- data                           |-- .babelrc                         // ES6语法编译配置
|-- .editorconfig                    // 定义代码格式
|-- .gitignore                       // git上传需要忽略的文件格式
|-- README.md                        // 项目说明
|-- favicon.ico
|-- index.html                       // 入口页面
|-- package.json                     // 项目基本信息,npm的包依赖安装信息
.

package.json(npm配置)

  • 他是项目根目录下的一个文件,定义该项目开发所需要的各种模块以及一些项目配置信息(如项目名称、版本、描述、作者等)

  • npm init初始化的时候就会生成这个文件,然后如果需要自定义就可以在里面编辑

{"name": "my-project-vue","version": "1.0.0","description": "A Vue.js project","author": "XXXXX","private": true,"scripts": { //来指定npm相关命令和通知npm执行这些命令"dev": "node build/dev-server.js", //根据不同的环境执行不同的文件,例如在开发环境下,在命令行中运行npm run dev就相当于在执行node build/dev-server.js"build": "node build/build.js","unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run","e2e": "node test/e2e/runner.js","test": "npm run unit && npm run e2e","lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"},"dependencies": { //指定了项目运行时所依赖的模块"ansi-html": "0.0.7","html-entities": "^1.2.0","strip-ansi": "^3.0.1","vue": "^2.1.10", //有vue"vue-router": "^2.2.0" //有vue-router},"devDependencies": { //指定了项目开发时所依赖的模块"autoprefixer": "^6.7.2","babel-core": "^6.22.1","babel-eslint": "^7.1.1","babel-loader": "^6.2.10","babel-plugin-istanbul": "^3.1.2","babel-plugin-transform-runtime": "^6.22.0","babel-preset-es2015": "^6.22.0","babel-preset-stage-2": "^6.22.0","babel-register": "^6.22.0","chai": "^3.5.0","chalk": "^1.1.3","chromedriver": "^2.27.2","connect-history-api-fallback": "^1.3.0","cross-env": "^3.1.4","cross-spawn": "^5.0.1","css-loader": "^0.26.1","eslint": "^3.14.1","eslint-config-standard": "^6.2.1","eslint-friendly-formatter": "^2.0.7","eslint-loader": "^1.6.1","eslint-plugin-html": "^2.0.0","eslint-plugin-promise": "^3.4.0","eslint-plugin-standard": "^2.0.1","eventsource-polyfill": "^0.9.6","express": "^4.14.1","extract-text-webpack-plugin": "^2.0.0-rc.2","file-loader": "^0.10.0","friendly-errors-webpack-plugin": "^1.1.3","function-bind": "^1.1.0","html-webpack-plugin": "^2.28.0","http-proxy-middleware": "^0.17.3","inject-loader": "^2.0.1","json-loader": "^0.5.4","karma": "^1.4.1","karma-coverage": "^1.1.1","karma-mocha": "^1.3.0","karma-phantomjs-launcher": "^1.0.2","karma-sinon-chai": "^1.2.4","karma-sourcemap-loader": "^0.3.7","karma-spec-reporter": "0.0.26","karma-webpack": "^2.0.2","lolex": "^1.5.2","mocha": "^3.2.0","nightwatch": "^0.9.12","opn": "^4.0.2","ora": "^1.1.0","phantomjs-prebuilt": "^2.1.14","selenium-server": "^3.0.1","semver": "^5.3.0","shelljs": "^0.7.6","sinon": "^1.17.7","sinon-chai": "^2.8.0","url-loader": "^0.5.7", "vue-loader": "^10.3.0",//vue-loader等"vue-style-loader": "^2.0.0", "vue-template-compiler": "^2.1.10","webpack": "^2.2.1","webpack-bundle-analyzer": "^2.2.1","webpack-dev-middleware": "^1.10.0","webpack-hot-middleware": "^2.16.1","webpack-merge": "^2.6.1"},"engines": { //顾名思义,就是告诉npm使用什么版本的node和npm"node": ">= 4.0.0","npm": ">= 3.0.0"}
}

这个package.json文件其实很长,不过主要关注一些日常使用到的就行了,全部配置在官方:https://docs.npmjs.com/files/package.json

webpack配置

使用npm run dev 就会执行dev-server.js,因为这个在packet.json里面配置了,所以需要知道dev-server.js里面有什么

dev-server.js

// 检查 Node 和 npm 版本(require指定loader)
require('./check-versions')()
// 获取config目录的默认配置,并且会默认指定index.js文件
var config = require('../config')
if (!process.env.NODE_ENV) {process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
// 一个可以强制打开浏览器并跳转到指定 url 的插件
var opn = require('opn')
// 使用 NodeJS 自带的文件路径工具
var path = require('path')
var express = require('express')
// 使用 webpack
var webpack = require('webpack')
// http-proxy可以实现转发所有请求代理到后端真实API地址,以实现前后端开发完全分离
// 使用 proxyTable
var proxyMiddleware = require('http-proxy-middleware')
// 判断是否使用 dev 环境的 webpack 配置
var webpackConfig = process.env.NODE_ENV === 'testing'? require('./webpack.prod.conf'): require('./webpack.dev.conf')// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
// 使用 config.dev.proxyTable 的配置作为 proxyTable 的代理配置
var proxyTable = config.dev.proxyTable
// 使用 express 启动一个服务
var app = express()
// 启动 webpack 进行编译
var compiler = webpack(webpackConfig)
// 启动 webpack-dev-middleware,将 编译后的文件暂存到内存中
var devMiddleware = require('webpack-dev-middleware')(compiler, {publicPath: webpackConfig.output.publicPath,quiet: true
})
/ 启动 webpack-hot-middleware,也就是我们常说的 Hot-reload 热加载
var hotMiddleware = require('webpack-hot-middleware')(compiler, {log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {hotMiddleware.publish({ action: 'reload' })cb()})
})// proxy api requests
Object.keys(proxyTable).forEach(function (context) {var options = proxyTable[context]if (typeof options === 'string') {options = { target: options }}app.use(proxyMiddleware(options.filter || context, options))
})// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())// serve webpack bundle output
// 将暂存到内存中的 webpack 编译后的文件挂在到 express 服务上
app.use(devMiddleware)// enable hot-reload and state-preserving
// compilation error display
// 将 Hot-reload 挂在到 express 服务上
app.use(hotMiddleware)// serve pure static assets
// 拼接 static 文件夹的静态资源路径
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
// 为静态资源提供响应服务
app.use(staticPath, express.static('./static'))var uri = 'http://localhost:' + portdevMiddleware.waitUntilValid(function () {console.log('> Listening at ' + uri + '\n')
})
// 让我们这个 express 服务监听 port 的请求,并且将此服务作为 dev-server.js 的接口暴露
module.exports = app.listen(port, function (err) {if (err) {console.log(err)return}// when env is testing, don't need open itif (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {opn(uri)}
})

备注:

  1. 加载器(Loaders) 引用
    loader 是对应用程序中资源文件进行转换。它们是(运行在 Node.js 中的) 函数,可以将资源文件作为参数的来源,然后返回新的资源文件。

例如,你可以使用 loader 告诉 webpack 加载 CSS 文件,或者将 TypeScript 转为 JavaScript。
loader 解析类似于模块。loader 模块需要导出(module.export)一个函数,并且使用兼容 Node.js 的 JavaScript 编写。在通常情况下,你可以使用 npm 管理 loader,但是你也可以在应用程序中将 loader 作为文件使用。

  1. 可以看到webpack其实使用了node.js的express网页服务器来进行处理网页相关的数据,相当于使用一个类似apache这样的web服务器来执行解析html等文件,只是这里换成了node.js的express,并且可以执行js文件

需要注意一点:require的时候,如果没有指定文件的话,有一些情况是会自定指定该目录下的index.js文件的,详情参考

webpack.dev.conf.js

dev-server.js的环境配置是调用webpack.dev.conf.js的,所以也需要看看了解一下

// 使用一些小工具
var utils = require('./utils')
// 使用 webpack
var webpack = require('webpack')
// 获取config目录的默认配置,并且会默认指定index.js文件
var config = require('../config')
// 使用 webpack 配置合并插件
var merge = require('webpack-merge')
// 加载 webpack.base.conf
var baseWebpackConfig = require('./webpack.base.conf')
// 使用 html-webpack-plugin 插件,这个插件可以帮我们自动生成 html 并且注入到 .html 文件中
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')// add hot-reload related code to entry chunks
// 将 Hol-reload 相对路径添加到 webpack.base.conf 的 对应 entry 前
Object.keys(baseWebpackConfig.entry).forEach(function (name) {baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
// 将我们 webpack.dev.conf.js 的配置和 webpack.base.conf.js 的配置合并
module.exports = merge(baseWebpackConfig, {module: {// 使用 styleLoadersrules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })},// cheap-module-eval-source-map is faster for developmentdevtool: '#cheap-module-eval-source-map',plugins: [// definePlugin 接收字符串插入到代码当中, 所以你需要的话可以写上 JS 的字符串new webpack.DefinePlugin({'process.env': config.dev.env}),// https://github.com/glenjamin/webpack-hot-middleware#installation--usage// HotModule 插件在页面进行变更的时候只会重回对应的页面模块,不会重绘整个 html 文件new webpack.HotModuleReplacementPlugin(),new webpack.NoEmitOnErrorsPlugin(),// https://github.com/ampedandwired/html-webpack-plugin// 将 index.html 作为入口,注入 html 代码后生成 index.html文件new HtmlWebpackPlugin({filename: 'index.html',template: 'index.html',inject: true}),new FriendlyErrorsPlugin()]
})

webpack.base.conf.js

webpack.dev.conf.js会导入webpack.base.conf.js,并且会进行合并配置

var path = require('path')
var utils = require('./utils')
var config = require('../config')
//加载了vue-loader,主要是我们这个项目是vue-cli构建的,所以相对配置也所特别
var vueLoaderConfig = require('./vue-loader.conf')
var eslintFriendlyFormatter = require('eslint-friendly-formatter')function resolve (dir) {return path.join(__dirname, '..', dir)
}module.exports = {entry: { //主要入口app: './src/main.js'},output: {path: config.build.assetsRoot,// 编译输出的根路径filename: '[name].js', //输出的文件名//判断是否dev环境来处理静态资源publicPath: process.env.NODE_ENV === 'production'? config.build.assetsPublicPath: config.dev.assetsPublicPath},resolve: {extensions: ['.js', '.vue', '.json'],modules: [resolve('src'),resolve('node_modules')],alias: {// 默认路径代理,例如 import Vue from 'vue',会自动到 'vue/dist/vue.common.js'中寻找'vue$': 'vue/dist/vue.common.js','src': resolve('src'),'assets': resolve('src/assets'),'components': resolve('src/components')}},module: {rules: [ //对不同文件使用不同的loader{test: /\.(js|vue)$/,loader: 'eslint-loader',enforce: "pre",include: [resolve('src'), resolve('test')],options: {formatter: eslintFriendlyFormatter}},{ //使用vue-loader解析.vue的文件test: /\.vue$/,loader: 'vue-loader',options: vueLoaderConfig},{ //普通的js文件使用babel-loader解析test: /\.js$/,loader: 'babel-loader',include: [resolve('src'), resolve('test')]},{ //其他差不多类似test: /\.json$/,loader: 'json-loader'},{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',query: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')}},{test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url-loader',query: {limit: 10000,name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]}
}

config/index.js

// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')module.exports = {build: { //如果是build的话就使用production环境配置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-pluginproductionGzip: 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 offbundleAnalyzerReport: process.env.npm_config_report},dev: { // dev的话就使用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}
}

可以看到dev是没有生成index.html之类的文件的,那是因为dev的话会直接在内存处理,方便调试,也可以利用热加载直接更新

参考:

  1. https://github.com/vuejs/vue-cli

  2. https://github.com/vuejs-templates/webpack

  3. https://segmentfault.com/a/1190000007880723

  4. https://gold.xitu.io/post/584e48b2ac502e006c74a120

  5. https://doc.webpack-china.org/configuration/

  6. https://webpack.js.org/configuration/

vue-cli学习入门_byKL相关推荐

  1. C++/CLI学习入门数组

    要学习数组,必须先了解跟踪句柄. 一.跟踪句柄 跟踪句柄类似于本地C++指针,但也有很大区别.跟踪句柄确实存储着某个对象的地址,但当CLR压缩堆过程中改变了该对象的地址,则垃圾回收器自动更新句柄所包含 ...

  2. Vue学习笔记(3)(Vue CLI)

    Vue2.x学习笔记.原视频教程:最全最新Vue.Vuejs教程,从入门到精通_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili Vue CLI 0. 什么是vue-cli 如果你在开发大型项目, ...

  3. Vue、Vuejs从入门到精通 | Vue CLI详解

    学习视频来源:B站<Vue.Vuejs从入门到精通> 个人在视频学习过程中也同步完成课堂练习等,现将授课材料与个人笔记分享出来. sudo npm install -g @vue/cli ...

  4. vue源码学习--vue源码学习入门

    本文为开始学习vue源码的思路整理.在拿到vue项目源码的之后看到那些项目中的文件夹,会很困惑,不知道每个文件夹内的世界,怎么变换,怎样的魔力,最后产生了vue框架.学习源码也无从学起.我解决了这些困 ...

  5. Vue.js 学习笔记十二:Vue CLI 之创建一个项目

    目录 创建一个项目 创建一个项目 运行以下命令来创建一个新项目: vue create vuecli-demo 你会被提示选取一个 preset.你可以选默认的包含了基本的 Babel + ESLin ...

  6. 【Vue学习笔记】尚硅谷Vue2.0+Vue3.0全套教程丨vue.js从入门到精通

    尚硅谷Vue2.0+Vue3.0全套教程丨vue.js从入门到精通 1.Vue核心部分 1.1 Vue简介 1.1.1 Vue是什么? Vue是一套用于构建用户界面的渐进式JavaScript框架. ...

  7. Vue框架的入门基础学习

    当创建新的vue项目时,遇到无法加载文件 E:\node\node_global\vue.ps1,因为在此系统上禁止运行脚本的错误,以下为解决办法. vue中文文档 菜鸟教程:Vue.js 该笔记只是 ...

  8. VUE学习-脚手架vue cli(六)

    一.脚手架vue cli 官网文档:https://cli.vuejs.org/zh/guide/ A)安装vue/cli 1.使用以下命令安装: npm install -g @vue/cli # ...

  9. 2018年最新Vue从基础入门到项目实战视频教程网盘学习地址

    2018年最新Vue从基础入门到项目实战视频教程网盘学习地址: https://pan.baidu.com/s/15D6GiHnSgA5Eo0n9G5Ws1A 若网盘地址失效,可访问此地址(下单有网盘 ...

最新文章

  1. 漫话:如何给女朋友解释什么是单例模式?
  2. 如果要和外国人做项目,加入一个teams是第一步,就跟我们的企业微信,钉钉差不多
  3. Android入门第十五篇之ActivityGroup + GridView 实现Tab分页标签
  4. 在阿里云 ECS 上配置 SSH
  5. java 程序是由什么组成的 java_从零开始的JAVA -2. java程序的构成及命名规则
  6. Excel数据生成SQL insert语句
  7. java报错空指针异常_夯实基础:认识一下这10 个深恶痛绝的 Java 异常
  8. 重磅资料!Github上的PHP资源汇总大全
  9. windows删文件:找不到该项目,该项目不在xx中,请确认位置,然后重试 的解决方案
  10. 计算机专业实习心得,计算机毕业实习心得体会范本5篇
  11. DBeaver Enterprise 算法注册机
  12. ios 凭据验证_iOS内购IAP(十四) —— IAP的收据验证(一)
  13. y的花式写法_y的花式写法_26个字母的花式写法,总有一个你喜欢哒
  14. 【LeetCode】求众数(四种方法)
  15. Maven子模块pom文件灰色下划线
  16. nginx上传文件大小报错500
  17. 爱奇艺播放按钮动画解析
  18. 基于51单片机的脉搏测量仪(心率计)
  19. 英文字符和数字间隔突然变大
  20. Raft一致性算法论文

热门文章

  1. 笑脸哭脸循环c语言,买卖信号(哭脸笑脸)选股公式(源码)
  2. python到底是啥_Python语言中的__init__到底是干什么的?
  3. js两个等号和三个等号_这两个号段开头的手机号,已成“古董号”,手里有的保存好...
  4. layui form模块
  5. QQ for Linux启动闪退问题
  6. 通用业务平台设计(二):扩展多国家业务
  7. SCPPO(十五):IIS配置文件节点加密
  8. 全面超越人类!Google称霸SQuAD,BERT横扫11大NLP测试
  9. Uber无人车事故又有新内情曝光:为竞争盲目冒进,瘾大技术差
  10. Apache RocketMQ 发布 v4.4.0,新添权限控制和消息轨迹特性