如果没有vue-cli,那么进行vue项目的开发环境配置将是很费力的一件事情,现在脚手架可以快速构建一个开发环境,是很不错的。不过对于脚手架构建的配置,还是要大概了解一下,方便自己调试配置。

初始化一个vue项目操作命令如下:

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

一般来说,vue-cli构建项目时候回生成类似下面的项目文件结构:

├─build
│ ├─build.js
│ ├─check-versions.js
│ ├─dev-client.js
│ ├─dev-server.js
│ ├─utils.js
│ ├─vue-loader.conf.js
│ ├─webpack.base.conf.js
│ ├─webpack.dev.conf.js
│ ├─webpack.prod.conf.js
├─config
│ ├─dev.env.js
│ ├─index.js
│ ├─prod.env.js
├─...
└─package.json

一、项目指令

我们可以在package.json里面的看到scripts字段是这样:

"scripts": {
"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"
}

这里包含开发运行,项目打包,单元测试等命令,测试的东西先放一边,看dev和build命令。运行”npm run dev”的时候执行的是build/dev-server.js文件,运行”npm run build”的时候执行的是build/build.js文件,我们可以从这两个文件开始进行代码阅读分析。

二、build文件夹配置

1、build/dev-server.js

这个文件主要是完成下面操作:

 检查node和npm的版本
引入相关插件和配置
创建express服务器和webpack编译器
配置开发中间件(webpack-dev-middleware)和热重载中间件(webpack-hot-middleware)
挂载代理服务和中间件
配置静态资源
启动服务器监听特定端口(8080)
自动打开浏览器并打开特定网址(localhost:8080)

Ps:express服务器提供静态文件服务,不过它还使用了http-proxy-middleware,一个http请求代理的中间件。前端开发过程中需要使用到后台的API的话,可以通过配置proxyTable来将相应的后台请求代理到专用的API服务器。

代码配置注释:

 // 检查NodeJS和npm的版本
require('./check-versions')() // 获取配置
var config = require('../config')
// 如果Node的环境变量中没有设置当前的环境(NODE_ENV),则使用config中的配置作为当前的环境
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
} // 一个可以调用默认软件打开网址、图片、文件等内容的插件
// 这里用它来调用默认浏览器打开dev-server监听的端口,例如:localhost:8080
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack') // 一个express中间件,用于将http请求代理到其他服务器
// 例:localhost:8080/api/xxx --> localhost:3000/api/xxx
// 这里使用该插件可以将前端开发中涉及到的请求代理到API服务器上,方便与服务器对接
var proxyMiddleware = require('http-proxy-middleware') // 根据 Node 环境来引入相应的 webpack 配置
var webpackConfig = process.env.NODE_ENV === 'testing'
? require('./webpack.prod.conf')
: require('./webpack.dev.conf') // dev-server 监听的端口,默认为config.dev.port设置的端口,即8080
var port = process.env.PORT || config.dev.port // 用于判断是否要自动打开浏览器的布尔变量,当配置文件中没有设置自动打开浏览器的时候其值为 false
var autoOpenBrowser = !!config.dev.autoOpenBrowser // 定义 HTTP 代理表,代理到 API 服务器
var proxyTable = config.dev.proxyTable // 创建1个 express 实例
var app = express() // 根据webpack配置文件创建Compiler对象
var compiler = webpack(webpackConfig) // webpack-dev-middleware使用compiler对象来对相应的文件进行编译和绑定
// 编译绑定后将得到的产物存放在内存中而没有写进磁盘
// 将这个中间件交给express使用之后即可访问这些编译后的产品文件
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
}) // webpack-hot-middleware,用于实现热重载功能的中间件
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
}) // 当html-webpack-plugin提交之后通过热重载中间件发布重载动作使得页面重载
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
}) // 将 proxyTable 中的代理请求配置挂在到express服务器上
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
// 格式化options,例如将'www.example.com'变成{ target: 'www.example.com' }
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
}) // handle fallback for HTML5 history API
// 重定向不存在的URL,常用于SPA
app.use(require('connect-history-api-fallback')()) // serve webpack bundle output
// 使用webpack开发中间件
// 即将webpack编译后输出到内存中的文件资源挂到express服务器上
app.use(devMiddleware) // enable hot-reload and state-preserving
// compilation error display
// 将热重载中间件挂在到express服务器上
app.use(hotMiddleware) // serve pure static assets
// 静态资源的路径
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) // 将静态资源挂到express服务器上
app.use(staticPath, express.static('./static')) // 应用的地址信息,例如:http://localhost:8080
var uri = 'http://localhost:' + port // webpack开发中间件合法(valid)之后输出提示语到控制台,表明服务器已启动
devMiddleware.waitUntilValid(function () {
console.log('> Listening at ' + uri + '\n')
}) // 启动express服务器并监听相应的端口(8080)
module.exports = app.listen(port, function (err) {
if (err) {
console.log(err)
return
} // when env is testing, don't need open it
// 如果符合自动打开浏览器的条件,则通过opn插件调用系统默认浏览器打开对应的地址uri
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
})

2、build/webpack.base.conf.js

从代码中看到,dev-server使用的webpack配置来自build/webpack.dev.conf.js文件(测试环境下使用的是build/webpack.prod.conf.js,这里暂时不考虑测试环境)。而build/webpack.dev.conf.js中又引用了webpack.base.conf.js,所以这里先看webpack.base.conf.js。

webpack.base.conf.js主要完成下面的操作:

 配置webpack编译入口
配置webpack输出路径和命名规则
配置模块resolve规则
配置不同类型模块的处理规则

代码配置注释:

 var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf') // 给出正确的绝对路径
function resolve (dir) {
return path.join(__dirname, '..', dir)
} module.exports = {
// 配置webpack编译入口
entry: {
app: './src/main.js'
}, // 配置webpack输出路径和命名规则
output: {
// webpack输出的目标文件夹路径(例如:/dist)
path: config.build.assetsRoot,
// webpack输出bundle文件命名格式
filename: '[name].js',
// webpack编译输出的发布路径
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
}, // 配置模块resolve的规则
resolve: {
// 自动resolve的扩展名
extensions: ['.js', '.vue', '.json'],
// resolve模块的时候要搜索的文件夹
modules: [
resolve('src'),
resolve('node_modules')
],
// 创建路径别名,有了别名之后引用模块更方便,例如
// import Vue from 'vue/dist/vue.common.js'可以写成 import Vue from 'vue'
alias: {
'vue$': 'vue/dist/vue.common.js',
'src': resolve('src'),
'assets': resolve('src/assets'),
'components': resolve('src/components')
}
}, // 配置不同类型模块的处理规则
module: {
rules: [
{// 对src和test文件夹下的.js和.vue文件使用eslint-loader
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: "pre",
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
{// 对所有.vue文件使用vue-loader
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{// 对src和test文件夹下的.js文件使用babel-loader
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{// 对图片资源文件使用url-loader,query.name指明了输出的命名规则
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{// 对字体资源文件使用url-loader,query.name指明了输出的命名规则
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}

3、build/webpack.dev.conf.js

接下来看webpack.dev.conf.js,这里面在webpack.base.conf的基础上增加完善了开发环境下面的配置,主要完成下面操作:

 将hot-reload相关的代码添加到entry chunks
合并基础的webpack配置
使用styleLoaders
配置Source Maps
配置webpack插件

代码配置注释:

 var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config') // 一个可以合并数组和对象的插件
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf') // 一个用于生成HTML文件并自动注入依赖文件(link/script)的webpack插件
var HtmlWebpackPlugin = require('html-webpack-plugin') // 用于更友好地输出webpack的警告、错误等信息
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])
}) // 合并基础的webpack配置
module.exports = merge(baseWebpackConfig, {
// 配置样式文件的处理规则,使用styleLoaders
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
}, // 配置Source Maps。在开发中使用cheap-module-eval-source-map更快
devtool: '#cheap-module-eval-source-map', // 配置webpack插件
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()
]
})

4、build/utils.js

utils主要完成下面3个操作:

 配置静态资源路径
生成cssLoaders用于加载.vue文件中的样式
生成styleLoaders用于加载不在.vue文件中的单独存在的样式文件

5、build/vue-loader.conf.js

vue-loader.conf则只配置了css加载器以及编译css之后自动添加前缀。

代码配置注释:

var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production' module.exports = {
// css加载器
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
}), // 让 vue-loader 知道需要对 audio 的 src 属性的内容转换为模块
transformToRequire: {
video: ‘src‘,
source: ‘src‘,
img: ‘src‘,
image: ‘xlink:href‘
}
}

6、build/build.js

build.js主要完成下面操作:

 loading动画
删除创建目标文件夹
webpack编译
输出信息

Ps: webpack编译之后会输出到配置里面指定的目标文件夹;删除目标文件夹之后再创建是为了去除旧的内容,以免产生不可预测的影响。

代码配置注释:

 // 检查NodeJS和npm的版本
require('./check-versions')() process.env.NODE_ENV = 'production' //ora插件,实现node.js 命令行环境的 loading效果, 和显示各种状态的图标等
var ora = require('ora')
var rm = require('rimraf')
var path = require('path') // 用于在控制台输出带颜色字体的插件
var chalk = require('chalk') var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf') var spinner = ora('building for production...')
spinner.start() //rimraf插件,每次启动编译或者打包之前,先把整个dist文件夹删除,然后再重新生成dist
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, 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') 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'
))
})
})

7、build/webpack.prod.conf.js

构建的时候用到的webpack配置来自webpack.prod.conf.js,该配置同样是在webpack.base.conf基础上的进一步完善。主要完成下面操作:

 合并基础的webpack配置
使用styleLoaders
配置webpack的输出
配置webpack插件
gzip模式下的webpack插件配置
webpack-bundle分析

代码配置注释:

 var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin') // 用于从webpack生成的bundle中提取文本到特定文件中的插件
// 可以抽取出css,js文件将其与webpack输出的bundle分离
var ExtractTextPlugin = require('extract-text-webpack-plugin') var env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: config.build.env // 合并基础的webpack配置
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
// 配置webpack的输出
output: {
// 编译输出目录
path: config.build.assetsRoot,
// 编译输出文件名格式
filename: utils.assetsPath('js/[name].[chunkhash].js'),
// 没有指定输出名的文件输出的文件名格式
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}, // 配置webpack插件
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}), // 丑化压缩代码
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}), // 抽离css文件
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}), // generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}), // split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
]
}) // gzip模式下需要引入compression插件进行压缩
if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
} if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
} module.exports = webpackConfig

8、build/check-versions.js

check-version.js完成对node和npm的版本检测。

代码配置注释:

 // 用于在控制台输出带颜色字体的插件
var chalk = require('chalk') // 语义化版本检查插件(The semantic version parser used by npm)
var semver = require('semver') // 引入package.json
var packageConfig = require('../package.json') // 开辟子进程执行指令cmd并返回结果
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
} // node和npm版本需求
var versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
{
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)
}
}

三、config文件夹

1、config/index.js

config文件夹下最主要的文件就是index.js了,在这里面描述了开发和构建两种环境下的配置,前面的build文件夹下也有不少文件引用了index.js里面的配置。

代码配置注释:

 // see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path') module.exports = {
// 构建产品时使用的配置
build: {
// webpack的编译环境
env: require('./prod.env'),
// 编译输入的index.html文件
index: path.resolve(__dirname, '../dist/index.html'),
// webpack输出的目标文件夹路径
assetsRoot: path.resolve(__dirname, '../dist'),
// webpack编译输出的二级文件夹
assetsSubDirectory: 'static',
// webpack编译输出的发布路径
assetsPublicPath: '/',
// 使用SourceMap
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
// 默认不打开开启gzip模式
productionGzip: false,
// gzip模式下需要压缩的文件的扩展名
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: {
// webpack的编译环境
env: require('./dev.env'),
// dev-server监听的端口
port: 8080,
// 启动dev-server之后自动打开浏览器
autoOpenBrowser: true,
// webpack编译输出的二级文件夹
assetsSubDirectory: 'static',
// webpack编译输出的发布路径
assetsPublicPath: '/',
// 请求代理表,在这里可以配置特定的请求代理到对应的API接口
// 例如将'/api/xxx'代理到'www.example.com/api/xxx'
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
cssSourceMap: false
}
}

Ps:config/dev.env.js、config/prod.env.js,这两个个文件就简单设置了环境变量而已,没什么特别。

vue-cli的webpack模板项目配置文件说明的更多相关文章

  1. vue-cli的webpack模板项目配置文件分析

    由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和config里面一些相关的配置,所以刚好趁此机会将所有配置文件看一遍,理一理思路,也便于以后修 ...

  2. [置顶] vue-cli的webpack模板项目配置文件分析

    2017-09-11更新:更新到webpack 2.6.1所对应的配置,完善部分代码注释. 由于最近在vue-cli生成的webpack模板项目的基础上写一个小东西,开发过程中需要改动到build和c ...

  3. 《转》vue-cli的webpack模板项目配置文件注释

    一.文件结构 本文主要分析开发(dev)和构建(build)两个过程涉及到的文件,故下面文件结构仅列出相应的内容. ├─build │ ├─build.js │ ├─check-versions.js ...

  4. 转:vue-cli的webpack模板项目配置文件分析

    转载地址:http://blog.csdn.net/hongchh/article/details/55113751 一.文件结构 本文主要分析开发(dev)和构建(build)两个过程涉及到的文件, ...

  5. vue-cli的webpack模板项目配置文件分析,配置信息详解

    比较不错的一篇详解文章: 地址:http://blog.csdn.net/hongchh/article/details/55113751#comments

  6. VUE知识day3_vue-cli脚手架安装和webpack模板项目生成

    ue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目. GitHub地址是:https://github.com/vuejs/vue-cli 一.安 ...

  7. 03慕课网《vue.js2.5入门》——Vue-cli的安装,创建webpack模板项目

    安装Vue-cli 第一种 貌似不可以,然后用了第二种,但是重装系统后,第二种不能用了,用了第一种可以 # 全局安装vue -cli命令npm install --global vue-cli # 创 ...

  8. vue cli 3.0创建项目

    .npm i -g @vue/cli .vue create my-project 此处有两个选择: 1.default (babel, eslint)默认套餐,提供babel和eslint支持 2. ...

  9. (尚018-第二章2.1)Vue使用vue-cli创建模板项目

    2.1.1 1)vue-cli是官方提供的脚手架工具(注意:脚手架本身是个库) 2)github:https://github.com/vuejs/vue-cli 3)作用:从https://gith ...

随机推荐

  1. 【数组】Spiral Matrix

    题目: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spira ...

  2. IntelliJ IDEA(Community版本)的下载、安装和WordCount的初步使用(本地模式和集群模式)

    不多说,直接上干货! 对于初学者来说,建议你先玩玩这个免费的社区版,但是,一段时间,还是去玩专业版吧,这个很简单哈,学聪明点,去搞到途径激活!可以看我的博客. 包括: IntelliJ IDEA(Co ...

  3. javac后期需要重点阅读的类

    (1)Annotate (300行) Enter annotations on symbols. Annotations accumulate in a queue,which is processe ...

  4. lucene源码分析(4)Similarity相似度算法

    lucene 7.5.0默认的评分Similarity是BM25Similarity (IndexSearcher.java) // the default Similarity private st ...

  5. android开发学习笔记系列(1)-android起航

    前言 在学习安卓的过程中,我觉得非常有必要将自己所学的东西进行整理,因为每每当我知道我应该是如何去实现功能的时候,有许多细节问题我总是会遗漏,因此我也萌生了写一系列博客来描述自己学习的路线,让我的an ...

  6. Golang panic用法

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  7. 求两个Linux文本文件的交集、差集、并集

    一.交集 sort a.txt b.txt | uniq -d 二.并集 sort a.txt b.txt | uniq 三.差集 a.txt-b.txt: sort a.txt b.txt b.tx ...

  8. 15.Generator 函数的语法

    Generator 函数的语法 Generator 函数的语法 简介 基本概念 Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同.本章详细介绍 Generat ...

  9. 使用 RetroShare 分享资源

    本文告诉大家如何使用 RetroShare 来分享资源.因为 RetroShare 是一个 p2p 分享的工具,所以他比现在很多云盘都好用,在网上,很多大神说可以用来代替电驴.之所以推荐这个软件,因为 ...

  10. JPA注解@GeneratedValue

    @GeneratedValue是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以看出. public enum GenerationType { TABLE, ...