npm i -D webpack@4 webpack-cli@3 webpack-dev-server@3
下載 pluginscss
npm i -D babel-polyfill happypack html-webpack-plugin clean-webpack-plugin progress-bar-webpack-plugin yargs-parser friendly-errors-webpack-plugin portfinder webpack-merge extract-text-webpack-plugin@next optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin chalk rimraf
npm i babel-loader @babel/cli @babel/core @babel/ @babel/preset-env plugin-proposal-class-properties @babel/ plugin-proposal-decorators @babel/ plugin-syntax-dynamic-import @babel/plugin-transform-classes @babel/plugin-transform-runtime -D
npm i --save @babel/runtime @babel/runtime-corejs2
{ "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage" }] ], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], "@babel/proposal-class-properties", ["@babel/plugin-transform-runtime", { "corejs": 2 }], "@babel/plugin-syntax-dynamic-import", "@babel/plugin-transform-classes" ] }
const os = require('os') //node OS模塊 可查看主機系統相關信息 const path = require('path') //node path模塊 c處理文件路徑 const utils = require('./utils') //vue-cli封裝的公用模塊 const webpack = require('webpack') const config = require('../config')//vue-cli封裝的配置 const HappyPack = require("happypack")//開啓多個子進程去併發執行 const HtmlWebpackPlugin = require('html-webpack-plugin')//webpack主要插件,能夠簡化HTML文件的建立 const CleanWebpackPlugin = require('clean-webpack-plugin');//清空打包好的文件 const ProgressBarPlugin = require('progress-bar-webpack-plugin')//查看進度 const vueLoaderConfig = require('./vue-loader.conf')// 處理less,sass等樣式配置文件 const VueLoaderPlugin = require('vue-loader/lib/plugin'); const argv = require("yargs-parser")(process.argv.slice(2))//獲取運行 scripts 裏面的指令 --mode 後面參數 const isPro = argv.mode == "production" const resolve = dir => path.resolve(__dirname, "..", dir) module.exports = { context: path.resolve(__dirname, '../'), entry: { app: ['babel-polyfill', './src/main.js']
}, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: isPro ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue': 'vue/dist/vue.esm.js', 'src': path.resolve(__dirname, '../src/common'), '@': resolve('src'), '~': resolve('src/components/common'), 'static': path.resolve(__dirname, '../static'), } }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.js$/, loaders: 'happypack/loader?id=babel',//配合 happypack插件使用 exclude: /(node_modules|bower_components)/, 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]') } } ] }, node: { setImmediate: false, dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' }, plugins: [ new ProgressBarPlugin(), new CleanWebpackPlugin(), new HappyPack({ id: 'babel', loaders: [{ loader: 'babel-loader', options: { babelrc: true, cacheDirectory: true, }, publicPath: "/" }], //共享進程池 threadPool: HappyPack.ThreadPool({ size: os.cpus().length //cpu nunbers }), //容許 HappyPack 輸出日誌 verbose: true, }), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify(argv.mode) } }), new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true, favicon: './src/assets/img/favicon.ico' }), new webpack.ProvidePlugin({//引入全局變量 $: 'jquery', jQuery: 'jquery', // 加上這個 }), new VueLoaderPlugin() ] }
'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge')//能夠合併 base.conf 配置文件 const baseWebpackConfig = require('./webpack.base.conf') const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')//讓日誌更加友好 const portfinder = require('portfinder') //查找開放端口或域接字的簡單工具 const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { mode:'development', module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, devtool: config.dev.devtool, devServer: { clientLogLevel: 'warning', historyApiFallback: true, hot: true, compress: true, host: HOST || config.dev.host, port: 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, }, disableHostCheck: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { if (err) { reject(err) } else { process.env.PORT = port devWebpackConfig.devServer.port = port // Add FriendlyErrorsPlugin devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) })
'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')//提取樣式文件,只有extract-text-webpack-plugin@^4.0.0-beta.0 才支持webpack4 //或者使用 mini-css-extract-plugin 用法詳見  const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') //用於優化\最小化 CSS const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 壓縮JS資源 const webpackConfig = merge(baseWebpackConfig, { mode: 'production', 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') }, optimization: { splitChunks: { chunks: 'all', // initial、async和all minSize: 30000, // 造成一個新代碼塊最小的體積 maxAsyncRequests: 5, // 按需加載時候最大的並行請求數 maxInitialRequests: 3, // 最大初始化請求數 automaticNameDelimiter: '~', // 打包分割符 name: true }, minimizer: [ new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[hash].css'), allChunks: true, }), new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, favicon: './src/assets/img/favicon.ico', minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, chunksSortMode: 'dependency' }), new webpack.optimize.ModuleConcatenationPlugin(), new CopyWebpackPlugin([{ from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] }]) ] } }) module.exports = webpackConfig
'use strict' require('./check-versions')() process.env.NODE_ENV = 'production' 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') rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err webpack(webpackConfig, (err, stats) => { 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(' 構建失敗,錯誤.\n')) process.exit(1) } console.log(chalk.cyan(' Build success.\n')) console.log(chalk.yellow( ' 打包文件應經過HTTP服務器啓用.\n' )) }) })
package.js (npm 配置)html
"scripts": { "dev": "webpack-dev-server --inline --mode development -- config build/webpack.dev.conf.js", "build": "node build/build.js " },