From c60e141e9b43be2eb5122eaa7da13bc0cf3848cd Mon Sep 17 00:00:00 2001 From: lyh <925863403@qq.com> Date: 星期五, 12 九月 2025 16:26:38 +0800 Subject: [PATCH] 起落架DNC初始化代码 --- build/build.js | 41 ++++ build/vue-loader.conf.js | 23 ++ build/utils.js | 98 +++++++++ build/webpack.prod.conf.js | 146 ++++++++++++++ build/webpack.base.conf.js | 79 +++++++ build/webpack.dev.conf.js | 79 +++++++ build/webpack.test.conf.js | 32 +++ build/check-versions.js | 49 ++++ build/logo.png | 0 9 files changed, 547 insertions(+), 0 deletions(-) diff --git a/build/build.js b/build/build.js new file mode 100644 index 0000000..b33234b --- /dev/null +++ b/build/build.js @@ -0,0 +1,41 @@ +'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(); + +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'); + + 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' + )) + }) +}); diff --git a/build/check-versions.js b/build/check-versions.js new file mode 100644 index 0000000..17352f3 --- /dev/null +++ b/build/check-versions.js @@ -0,0 +1,49 @@ +'use strict'; +const chalk = require('chalk'); +const semver = require('semver'); +const packageConfig = require('../package.json'); +const shell = require('shelljs'); +function exec (cmd) { + return require('child_process').execSync(cmd).toString().trim() +} + +const versionRequirements = [ + { + name: 'node', + 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 () { + const warnings = []; + for (let i = 0; i < versionRequirements.length; i++) { + const 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 (let i = 0; i < warnings.length; i++) { + const warning = warnings[i] + console.log(' ' + warning) + } + console.log(); + process.exit(1) + } +}; diff --git a/build/logo.png b/build/logo.png new file mode 100644 index 0000000..f3d2503 --- /dev/null +++ b/build/logo.png Binary files differ diff --git a/build/utils.js b/build/utils.js new file mode 100644 index 0000000..72bd579 --- /dev/null +++ b/build/utils.js @@ -0,0 +1,98 @@ +'use strict'; +const path = require('path'); +const config = require('../config'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const pkg = require('../package.json'); + +exports.assetsPath = function (_path) { + const assetsSubDirectory = process.env.NODE_ENV === 'production' + ? config.build.assetsSubDirectory + : config.dev.assetsSubDirectory + return path.posix.join(assetsSubDirectory, _path) +}; + +exports.cssLoaders = function (options) { + options = options || {}; + + const cssLoader = { + loader: 'css-loader', + options: { + sourceMap: options.sourceMap + } + }; + + var postcssLoader = { + loader: 'postcss-loader', + options: { + sourceMap: options.sourceMap + } + }; + + // generate loader string to be used with extract text plugin + function generateLoaders (loader, loaderOptions) { + const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]; + if (loader) { + loaders.push({ + loader: loader + '-loader', + options: Object.assign({}, loaderOptions, { + sourceMap: options.sourceMap + }) + }) + } + + // Extract CSS when that option is specified + // (which is the case during production build) + if (options.extract) { + return ExtractTextPlugin.extract({ + use: loaders, + fallback: 'vue-style-loader' + }) + } else { + return ['vue-style-loader'].concat(loaders) + } + } + + // https://vue-loader.vuejs.org/en/configurations/extract-css.html + return { + css: generateLoaders(), + postcss: generateLoaders(), + less: generateLoaders('less'), + sass: generateLoaders('sass', { indentedSyntax: true }), + scss: generateLoaders('sass'), + stylus: generateLoaders('stylus'), + styl: generateLoaders('stylus') + } +}; + +// Generate loaders for standalone style files (outside of .vue) +exports.styleLoaders = function (options) { + const output = []; + const loaders = exports.cssLoaders(options); + for (const extension in loaders) { + const loader = loaders[extension]; + output.push({ + test: new RegExp('\\.' + extension + '$'), + use: loader + }) + } + return output +}; + +exports.createNotifierCallback = function () { + const notifier = require('node-notifier'); + + return (severity, errors) => { + if (severity !== 'error') { + return + } + const error = errors[0]; + + const filename = error.file && error.file.split('!').pop(); + notifier.notify({ + title: pkg.name, + message: severity + ': ' + error.name, + subtitle: filename || '', + icon: path.join(__dirname, 'logo.png') + }) + } +}; diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js new file mode 100644 index 0000000..2a14fa1 --- /dev/null +++ b/build/vue-loader.conf.js @@ -0,0 +1,23 @@ +'use strict'; +const utils = require('./utils'); +const config = require('../config'); +const isProduction = process.env.NODE_ENV === 'production'; +const sourceMapEnabled = isProduction + ? config.build.productionSourceMap + : config.dev.cssSourceMap; + + +module.exports = { + loaders: utils.cssLoaders({ + sourceMap: sourceMapEnabled, + extract: isProduction + }), + cssSourceMap: sourceMapEnabled, + cacheBusting: config.dev.cacheBusting, + transformToRequire: { + video: 'src', + source: 'src', + img: 'src', + image: 'xlink:href' + } +}; diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js new file mode 100644 index 0000000..d4b6ca6 --- /dev/null +++ b/build/webpack.base.conf.js @@ -0,0 +1,79 @@ +'use strict'; +const path = require('path'); +const utils = require('./utils'); +const config = require('../config'); +const vueLoaderConfig = require('./vue-loader.conf'); + +function resolve (dir) { + return path.join(__dirname, '..', dir) +} + +module.exports = { + context: path.resolve(__dirname, '../'), + entry: { + app: './src/main.js' + }, + output: { + path: config.build.assetsRoot, + filename: '[name].js', + publicPath: process.env.NODE_ENV === 'production' + ? config.build.assetsPublicPath + : config.dev.assetsPublicPath + }, + resolve: { + extensions: ['.js', '.vue', '.json'], + alias: { + 'vue$': 'vue/dist/vue.esm.js', + '@': resolve('src'), + 'scss_vars': '@/statics/css/vars.scss' + } + }, + module: { + rules: [ + // ...(config.dev.useEslint? [{ + // test: /\.(js|vue)$/, + // loader: 'eslint-loader', + // enforce: 'pre', + // include: [resolve('src'), resolve('test')], + // options: { + // formatter: require('eslint-friendly-formatter'), + // emitWarning: !config.dev.showEslintErrorsInOverlay + // } + // }] : []), + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueLoaderConfig + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [resolve('src'), resolve('test')] + }, + { + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('img/[name].[hash:7].[ext]') + } + }, + { + test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('media/[name].[hash:7].[ext]') + } + }, + { + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, + loader: 'url-loader', + options: { + limit: 10000, + name: utils.assetsPath('fonts/[name].[hash:7].[ext]') + } + } + ] + } +}; diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js new file mode 100644 index 0000000..d1d9623 --- /dev/null +++ b/build/webpack.dev.conf.js @@ -0,0 +1,79 @@ +'use strict'; +const utils = require('./utils'); +const webpack = require('webpack'); +const config = require('../config'); +const merge = require('webpack-merge'); +const baseWebpackConfig = require('./webpack.base.conf'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); +const portfinder = require('portfinder'); + +const devWebpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) + }, + // cheap-module-eval-source-map is faster for development + devtool: config.dev.devtool, + + // these devServer options should be customized in /config/index.js + devServer: { + disableHostCheck:true, + clientLogLevel: 'warning', + historyApiFallback: true, + hot: true, + compress: true, + host: process.env.HOST ||聽config.dev.host, + port: process.env.PORT ||聽config.dev.port, + open: config.dev.autoOpenBrowser, + overlay: config.dev.errorOverlay ? { + warnings: false, + errors: true, + } : false, + publicPath: config.dev.assetsPublicPath, + proxy: config.dev.proxyTable, + quiet: true, // necessary for FriendlyErrorsPlugin + watchOptions: { + poll: config.dev.poll, + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/dev.env') + }), + new webpack.HotModuleReplacementPlugin(), + new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. + new webpack.NoEmitOnErrorsPlugin(), + // https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', + template: 'index.html', + inject: true + }), + ] +}); + +module.exports = new Promise((resolve, reject) => { + portfinder.basePort = process.env.PORT || config.dev.port; + portfinder.getPort((err, port) => { + if (err) { + reject(err); + } else { + // publish the new Port, necessary for e2e tests + process.env.PORT = port; + // add port to devServer config + devWebpackConfig.devServer.port = port; + + // Add FriendlyErrorsPlugin + devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ + compilationSuccessInfo: { + messages: [`Your application is running here: http://${config.dev.host}:${port}`], + }, + onErrors: config.dev.notifyOnErrors + ? utils.createNotifierCallback() + : undefined + })); + + resolve(devWebpackConfig); + } + }) +}); diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js new file mode 100644 index 0000000..a6efc0f --- /dev/null +++ b/build/webpack.prod.conf.js @@ -0,0 +1,146 @@ +'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'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin'); + +const env = process.env.NODE_ENV === 'testing' + ? require('../config/test.env') + : require('../config/prod.env'); + +const webpackConfig = merge(baseWebpackConfig, { + module: { + rules: utils.styleLoaders({ + sourceMap: config.build.productionSourceMap, + extract: true, + usePostCSS: true + }) + }, + devtool: config.build.productionSourceMap ? config.build.devtool : false, + output: { + path: config.build.assetsRoot, + filename: utils.assetsPath('js/[name].[chunkhash].js'), + chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') + }, + plugins: [ + // http://vuejs.github.io/vue-loader/en/workflow/production.html + new webpack.DefinePlugin({ + 'process.env': env + }), + // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + }, + sourceMap: config.build.productionSourceMap, + parallel: true + }), + // extract css into its own file + new ExtractTextPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css'), + // set the following option to `true` if you want to extract CSS from + // codesplit chunks into this main css file as well. + // This will result in *all* of your app's CSS being loaded upfront. + allChunks: false, + }), + // 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({ + 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 vender 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: function (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: ['.*'] + } + ]) + ] +}); + +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; diff --git a/build/webpack.test.conf.js b/build/webpack.test.conf.js new file mode 100644 index 0000000..7d0f45e --- /dev/null +++ b/build/webpack.test.conf.js @@ -0,0 +1,32 @@ +'use strict'; +// This is the webpack config used for unit tests. + +const utils = require('./utils'); +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const baseWebpackConfig = require('./webpack.base.conf'); + +const webpackConfig = merge(baseWebpackConfig, { + // use inline sourcemap for karma-sourcemap-loader + module: { + rules: utils.styleLoaders() + }, + devtool: '#inline-source-map', + resolveLoader: { + alias: { + // necessary to to make lang="scss" work in test when using vue-loader's ?inject option + // see discussion at https://github.com/vuejs/vue-loader/issues/724 + 'scss-loader': 'sass-loader' + } + }, + plugins: [ + new webpack.DefinePlugin({ + 'process.env': require('../config/test.env') + }) + ] +}); + +// no need for app entry during tests +delete webpackConfig.entry; + +module.exports = webpackConfig; -- Gitblit v1.9.3