vue中npm run build打包编译的一系列操作

从package.json 中可以看出,npm run build,其实是执行了 node build/build.js,我们在build文件夹中找到build.js,build主要的工作是:检测node和npm版本,删除dist包,webpack构建打包,在终端输出构建信息并结束,如果报错,则输出报错信息。

'use strict'
require( './check-versions')()

process. env.NODE_ENV = 'production'

const ora = require( 'ora') // 在终端显示的旋转器插件
const rm = require( 'rimraf') // 用于删除文件夹
const path = require( 'path')
const chalk = require( 'chalk') // 终端文字颜色插件
const webpack = require( 'webpack')
const config = require( '../config')
const webpackConfig = require( './webpack.prod.conf')

const spinner = ora( 'building for production...')
spinner. start()
// 删除dist文件夹,之后webpack打包
rm( path. join( config. build. assetsRoot, config. build. assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, ( err, stats) => {
spinner. stop()
if (err) throw err
process. stdout. write( stats. toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
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 '
))
})
})

build.js用到了webpack.prod.conf.js,他与webpack.base.conf.js merge之后,作为webpack配置文件,我们再看看webpack.prod.conf.js,主要做的工作是:
1.提取webpack生成的bundle中的文本,到特定的文件,使得css,js文件与webpack输出的bundle分离。

2.合并基本的webpack配置

3.配置webpack的输出,包括输出路径,文件名格式。

4.配置webpack插件,包括丑化代码。

5.gzip下引入compression插件进行压缩。

'use strict'
const path = require( 'path')
const utils = require( './utils')
const webpack = require( 'webpack')
const config = require( '../config')
const merge = require( 'webpack-merge')
const baseWebpackConfig = require( './webpack.base.conf')
const CopyWebpackPlugin = require( 'copy-webpack-plugin')
const HtmlWebpackPlugin = require( 'html-webpack-plugin')
// 用于从webpack生成的bundle中提取文本到特定文件中的插件
// 可以抽取出css,js文件将其与webpack输出的bundle分离
const ExtractTextPlugin = require( 'extract-text-webpack-plugin')
const OptimizeCSSPlugin = require( 'optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require( 'uglifyjs-webpack-plugin')

const env = process. env.NODE_ENV === 'testing'
? require( '../config/test.env')
: require( '../config/prod.env')
// 合并基础的webpack配置
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils. styleLoaders({
sourceMap: config. build. productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config. build. productionSourceMap ? config. build. devtool : false,
// 配置webpack输出的目录,及文件命名规则
output: {
path: config. build. assetsRoot,
filename: utils. assetsPath( "js/[name].[chunkhash].js"),
chunkFilename: utils. assetsPath( "js/[id].[chunkhash].js")
},
plugins: [
// webpack插件配置
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack. DefinePlugin({
"process.env": env
}),
// 丑化代码
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config. build. productionSourceMap,
parallel: true
}),
// // 抽离css文件到单独的文件
new ExtractTextPlugin({
filename: utils. assetsPath( "css/[name].[contenthash].css"),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config. build. productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// 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({
// 生成并注入index.html
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"
}),
// keep module.id stable when vendor modules does not change
new webpack. HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack. optimize. ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack. optimize. CommonsChunkPlugin({
name: "vendor",
minChunks( module) {
// 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",
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack. optimize. CommonsChunkPlugin({
name: "app",
async: "vendor-async",
children: true,
minChunks: 3
}),

// copy custom static assets
new CopyWebpackPlugin([
{
from: path. resolve( __dirname, "../static"),
to: config. build. assetsSubDirectory,
ignore: [ ".*"]
}
])
]
});
// gzip模式下需要引入compression插件进行压缩
if ( config. build. productionGzip) {
const 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) {
const BundleAnalyzerPlugin = require( 'webpack-bundle-analyzer'). BundleAnalyzerPlugin
webpackConfig. plugins. push( new BundleAnalyzerPlugin())
}

module. exports = webpackConfig

总结:执行npm run dev或者npm run start,实际是在node环境执行build/dev-server.js, dev-server.js会去拿到config中的端口等配置,通过express起一个服务,通过插件自动打开浏览器,加载webpack编译后放在内存的bundle。

执行npm run build,实际上执行了build/build.js,通过webpack的一系列配置及插件,将文件打包合并丑化,并创建dist目录,放置编译打包后的文件,这将是未来用在生产环境的包。


猜你喜欢

转载自blog.csdn.net/qq_40190624/article/details/80175691