折腾:
【已解决】如何把react-hot-boilerplate的项目打包为生产环境
后,对于之前常见的,npm run build之前和之后要做的一些事情,
一直希望写个脚本自动运行,以减少手动的操作的浪费时间
现在终于经过一番折腾,基本上实现了,部分的工作的自动化。
参考别人的:
“scripts”: { “dev”: “cross-env NODE_ENV=development webpack-dev-server –inline –hot –progress”, “start”: “serve build -s -c 1”, “prestart”: “npm run build”, “build”: “cross-env NODE_ENV=production webpack -p –progress”, “prebuild”: “mkdirp build && ncp src/assets build/assets”, “lint”: “eslint src” }, |
自己去加上自己的逻辑,最后为:
“prebuild”: “rm -rf build build.zip && mkdir -p build/dist && ncp src/assets build/dist && cp index.html build”, “build”: “npm run prebuild && cross-env NODE_ENV=production webpack -p –progress –colors && npm run postbuild”, “postbuild”: “zip -r build.zip build” |
此处的prebuild和build,postbuild是自己写的。
注:
此处需要先去安装ncp工具:
npm install ncp
对于上述写法,直接运行npm run build,即可起到所需要的效果:
➜ react-hot-boilerplate git:(master) ✗ npm run build > [email protected] prebuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > rm -rf build build.zip && mkdir -p build/dist && ncp src/assets build/dist && cp index.html build > [email protected] build /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > npm run prebuild && cross-env NODE_ENV=production webpack -p –progress –colors && npm run postbuild > [email protected] prebuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > rm -rf build build.zip && mkdir -p build/dist && ncp src/assets build/dist && cp index.html build process.env.NODE_ENV=production, isProd=true Hash: 2993b4a31f252f080d48 Version: webpack 3.5.4 Time: 43424ms Asset Size Chunks Chunk Names index.js 1.12 MB 0 [emitted] [big] index vendor.bundle.js 11 kB 1 [emitted] vendor [207] (webpack)/buildin/module.js 521 bytes {0} [built] [237] (webpack)/buildin/global.js 823 bytes {0} [built] [303] ./src/index.js 467 bytes {0} [built] [392] ./src/App.js 15.3 kB {0} [built] [757] ./src/app.css 994 bytes {0} [built] [758] ./node_modules/css-loader!./src/app.css 439 bytes {0} [built] [762] multi react-hot-loader/patch ./src/adminlte_app.js 40 bytes {1} [built] [766] ./src/adminlte_app.js 22.6 kB {1} [built] + 759 hidden modules > [email protected] postbuild /Users/crifan/dev/dev_root/daryun/Projects/xxxsourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > zip -r build.zip build adding: build/ (stored 0%) adding: build/dist/ (stored 0%) adding: build/dist/.DS_Store (deflated 97%) adding: build/dist/img/ (stored 0%) adding: build/dist/img/avatar.png (stored 0%) adding: build/dist/img/avatar04.png (stored 0%) adding: build/dist/img/avatar2.png (stored 0%) adding: build/dist/img/avatar3.png (stored 0%) adding: build/dist/img/avatar5.png (stored 0%) adding: build/dist/img/boxed-bg.jpg (deflated 7%) adding: build/dist/img/boxed-bg.png (deflated 0%) adding: build/dist/img/credit/ (stored 0%) adding: build/dist/img/credit/american-express.png (stored 0%) adding: build/dist/img/credit/cirrus.png (stored 0%) adding: build/dist/img/credit/mastercard.png (stored 0%) adding: build/dist/img/credit/mestro.png (stored 0%) adding: build/dist/img/credit/paypal.png (stored 0%) adding: build/dist/img/credit/paypal2.png (stored 0%) adding: build/dist/img/credit/visa.png (stored 0%) adding: build/dist/img/default-50×50.gif (deflated 7%) adding: build/dist/img/icons.png (deflated 2%) adding: build/dist/img/photo1.png (deflated 0%) adding: build/dist/img/photo2.png (deflated 0%) adding: build/dist/img/photo3.jpg (deflated 1%) adding: build/dist/img/photo4.jpg (deflated 1%) adding: build/dist/img/user1-128×128.jpg (deflated 5%) adding: build/dist/img/user2-160×160.jpg (deflated 3%) adding: build/dist/img/user3-128×128.jpg (deflated 5%) adding: build/dist/img/user4-128×128.jpg (deflated 0%) adding: build/dist/img/user5-128×128.jpg (deflated 2%) adding: build/dist/img/user6-128×128.jpg (deflated 3%) adding: build/dist/img/user7-128×128.jpg (deflated 2%) adding: build/dist/img/user8-128×128.jpg (deflated 3%) adding: build/index.html (deflated 68%) adding: build/index.js (deflated 69%) adding: build/vendor.bundle.js (deflated 67%) > [email protected] postbuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > zip -r build.zip build updating: build/ (stored 0%) updating: build/dist/ (stored 0%) updating: build/dist/.DS_Store (deflated 97%) updating: build/dist/img/ (stored 0%) updating: build/dist/img/avatar.png (stored 0%) updating: build/dist/img/avatar04.png (stored 0%) updating: build/dist/img/avatar2.png (stored 0%) updating: build/dist/img/avatar3.png (stored 0%) updating: build/dist/img/avatar5.png (stored 0%) updating: build/dist/img/boxed-bg.jpg (deflated 7%) updating: build/dist/img/boxed-bg.png (deflated 0%) updating: build/dist/img/credit/ (stored 0%) updating: build/dist/img/credit/american-express.png (stored 0%) updating: build/dist/img/credit/cirrus.png (stored 0%) updating: build/dist/img/credit/mastercard.png (stored 0%) updating: build/dist/img/credit/mestro.png (stored 0%) updating: build/dist/img/credit/paypal.png (stored 0%) updating: build/dist/img/credit/paypal2.png (stored 0%) updating: build/dist/img/credit/visa.png (stored 0%) updating: build/dist/img/default-50×50.gif (deflated 7%) updating: build/dist/img/icons.png (deflated 2%) updating: build/dist/img/photo1.png (deflated 0%) updating: build/dist/img/photo2.png (deflated 0%) updating: build/dist/img/photo3.jpg (deflated 1%) updating: build/dist/img/photo4.jpg (deflated 1%) updating: build/dist/img/user1-128×128.jpg (deflated 5%) updating: build/dist/img/user2-160×160.jpg (deflated 3%) updating: build/dist/img/user3-128×128.jpg (deflated 5%) updating: build/dist/img/user4-128×128.jpg (deflated 0%) updating: build/dist/img/user5-128×128.jpg (deflated 2%) updating: build/dist/img/user6-128×128.jpg (deflated 3%) updating: build/dist/img/user7-128×128.jpg (deflated 2%) updating: build/dist/img/user8-128×128.jpg (deflated 3%) updating: build/index.html (deflated 68%) updating: build/index.js (deflated 69%) updating: build/vendor.bundle.js (deflated 67%) |
【总结】
对应的文件夹结构和文件是:
此处的逻辑是:
npm run build
会先去运行:
npm run prebuild
在运行npm build部分的内容
最后再去执行:
npm run postbuild
分别的含义是:
1.npm run prebuild
(1)rm -rf build build.zip
删除(之前)创建的build文件夹和(之前)压缩出来的文件build.zip
(2)mkdir -p build/dist
创建build和build/dist文件夹
(3)ncp src/assets build/dist
把src下面的assets(其中包括img等文件)整个文件夹的都复制到build/dist
(4)cp index.html build
把html的index.html文件拷贝到build文件夹中
2.npm run build
(1)npm run prebuild
在运行build之前,先去执行创建文件夹等工作
(2)cross-env NODE_ENV=production webpack -p –progress —colors
执行webpack -p的给production打包
(3)npm run postbuild
在build之后执行一些动作,包括压缩打包
3.npm run postbuild
(1)zip -r build.zip build
把build文件夹及其下的文件都压缩打包为build.zip
【后记1】
后来看到别处的:
new CopyWebpackPlugin([ { from: ‘./manifest.json’, to: ‘./’ }, { from: ‘./favicon.ico’, to: ‘./’ } ]) |
所以去搜索:
CopyWebpackPlugin
GitHub – kevlened/copy-webpack-plugin: Copy files and directories in webpack
是去把文件(夹)拷贝到build的文件夹
所以去试试:
➜ react-hot-boilerplate git:(master) ✗ npm install –save-dev copy-webpack-plugin npm WARN [email protected] requires a peer of webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc but none was installed. npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed. added 8 packages in 10.011s |
经过尝试,结果是:
用:
// import CopyWebpackPlugin from ‘copy-webpack-plugin’; var CopyWebpackPlugin = require(‘copy-webpack-plugin’); var isProd = (process.env.NODE_ENV === ‘production’); let commonPlugins = [ new webpack.optimize.CommonsChunkPlugin({ name: ‘vendor’, filename: ‘vendor.bundle.js’ }), ]; if (isProd) { commonPlugins.push( new CopyWebpackPlugin([ //{ from: ‘./index.html’, to: ‘build’ }, // { from: ‘src/assets’, to: ‘build/dist’ }, { from: ‘./index.html’ }, { from: ‘src/assets’, to: ‘dist’ }, ]) ); } module.exports = { … plugins: commonPlugins, } |
不需要之前的:
mkdir -p build/dist
去创建对应的build以及build/dist文件夹了。
就可以取代之前的:
ncp src/assets build/dist && cp index.html build
去拷贝对应的文件和图片,并且自动创建对应的目标文件夹了。
优化后的代码为:
package.json
“scripts”: { 。。。 “prebuild”: “rm -rf build build.zip”, “build”: “npm run prebuild && cross-env NODE_ENV=production webpack -p –progress –colors && npm run postbuild”, “postbuild”: “zip -r build.zip build” }, |
webpack.config.js
// import CopyWebpackPlugin from ‘copy-webpack-plugin’; var CopyWebpackPlugin = require(‘copy-webpack-plugin’); var path = require(‘path’); var webpack = require(‘webpack’); // const ENV = process.env.NODE_ENV || ‘development’; var isProd = (process.env.NODE_ENV === ‘production’); console.log(`process.env.NODE_ENV=${process.env.NODE_ENV}, isProd=${isProd}`); //process.env.NODE_ENV=development, isProd=false let commonPlugins = [ // new webpack.ProvidePlugin({ // $: ‘jquery’, // ‘window.jQuery’: ‘jquery’, // jQuery: ‘jquery’, // ‘window.$’: ‘jquery’, // }), new webpack.optimize.CommonsChunkPlugin({ name: ‘vendor’, filename: ‘vendor.bundle.js’ }), // new webpack.HotModuleReplacementPlugin() ]; if (isProd) { // Note: current not add UglifyJsPlugin for production for: // when webpack -p, it will auto added UglifyJsPlugin, then omit here UglifyJsPlugin settings // commonPlugins.push( // new webpack.optimize.UglifyJsPlugin({ // minimize: true // }) // ); commonPlugins.push( new CopyWebpackPlugin([ //{ from: ‘./index.html’, to: ‘build’ }, // { from: ‘src/assets’, to: ‘build/dist’ }, { from: ‘./index.html’ }, { from: ‘src/assets’, to: ‘dist’ }, ]) ); } module.exports = { entry: { index: ‘./src/index.js’, vendor : [ // ‘webpack-hot-middleware/client’, ‘react-hot-loader/patch’, ‘./src/adminlte_app.js’ ], }, output: { // path: path.join(__dirname, ‘public’), // path: path.join(__dirname, ‘build’), path: path.resolve(__dirname, ‘build’), // filename: ‘bundle.js’, filename: ‘[name].js’, // filename: ‘./build/[name].js’, // publicPath: ‘/public/’ // publicPath: ‘/public’ // publicPath: ‘/assets/’ // publicPath: ‘http://localhost:3000/public/’ }, // devtool: isProd ? ‘cheap-module-source-map’ : ‘eval’, devtool: isProd ? ‘false’ : ‘eval’, devServer:{ // hot: true, // contentBase: path.join(__dirname, ‘dist’), contentBase: path.resolve(__dirname, ‘build’), // publicPath: path.resolve(__dirname, ‘build’), compress: true, port: 3000, historyApiFallback: true }, plugins: commonPlugins, module: { // loaders: [ rules: [ { test: /\.js$/, //loaders: [‘react-hot-loader’, ‘babel-loader’], // use: [‘react-hot-loader’, ‘babel-loader’], use: [‘babel-loader’], // include: path.join(__dirname, ‘src’) }, { test: /\.css$/, // loaders: [‘style-loader’, ‘css-loader’], use: [‘style-loader’, ‘css-loader’], // include: path.join(__dirname, ‘src’) } ] } }; |
即可。
【后记2】
后来参考别的项目时注意到:
build中,并没有显式地调用prebuild,但是npm run build会自动先去执行prebuild
所以搜:
prebuild build npm run
参考:
得知:
七、钩子 npm 脚本有pre和post两个钩子。举例来说,build脚本命令的钩子就是prebuild和postbuild。 “prebuild”: “echo I run before the build script”, “build”: “cross-env NODE_ENV=production webpack”, “postbuild”: “echo I run after the build script” 用户执行npm run build的时候,会自动按照下面的顺序执行。 npm run prebuild && npm run build && npm run postbuild 因此,可以在这两个钩子里面,完成一些准备工作和清理工作。下面是一个例子。 “clean”: “rimraf ./dist && mkdir dist”, “prebuild”: “npm run clean”, “build”: “cross-env NODE_ENV=production webpack” npm 默认提供下面这些钩子。 prepublish,postpublish preinstall,postinstall preuninstall,postuninstall preversion,postversion pretest,posttest prestop,poststop prestart,poststart prerestart,postrestart 自定义的脚本命令也可以加上pre和post钩子。比如,myscript这个脚本命令,也有premyscript和postmyscript钩子。不过,双重的pre和post无效,比如prepretest和postposttest是无效的。 npm 提供一个npm_lifecycle_event变量,返回当前正在运行的脚本名称,比如pretest、test、posttest等等。所以,可以利用这个变量,在同一个脚本文件里面,为不同的npm scripts命令编写代码。请看下面的例子。 const TARGET = process.env.npm_lifecycle_event; if (TARGET === ‘test’) { console.log(`Running the test task!`); } if (TARGET === ‘pretest’) { console.log(`Running the pretest task!`); } if (TARGET === ‘posttest’) { console.log(`Running the posttest task!`); } 注意,prepublish这个钩子不仅会在npm publish命令之前运行,还会在npm install(不带任何参数)命令之前运行。这种行为很容易让用户感到困惑,所以 npm 4 引入了一个新的钩子prepare,行为等同于prepublish,而从 npm 5 开始,prepublish将只在npm publish命令之前运行。 |
所以,之前脚本可以去掉调用npm run prebuild和npm run postbuild,且还可以再加上clean,变为:
“scripts”: { “dev”: “cross-env NODE_ENV=development webpack-dev-server –progress –colors –hot –inline –open”, “lint”: “eslint src”, “clean” : “rm -rf build/ build.zip”, “package” : “zip -r build.zip build/”, “prebuild”: “npm run clean”, “build”: “cross-env NODE_ENV=production webpack -p –progress –colors”, “postbuild”: “npm run package” }, |
然后运行
npm run build
会自动先后执行prebuild和postbuild:
➜ react-hot-boilerplate git:(master) ✗ npm run build > [email protected] prebuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > npm run clean > [email protected] clean /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > rm -rf build/ build.zip > [email protected] build /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > cross-env NODE_ENV=production webpack -p –progress –colors process.env.NODE_ENV=production, isProd=true Hash: 2993b4a31f252f080d48 Version: webpack 3.5.4 Time: 40799ms Asset Size Chunks Chunk Names dist/img/credit/mestro.png 1.59 kB [emitted] index.js 1.12 MB 0 [emitted] [big] index index.html 2.55 kB [emitted] dist/.DS_Store 6.15 kB [emitted] dist/img/.DS_Store 6.15 kB [emitted] dist/img/avatar.png 8.54 kB [emitted] dist/img/avatar04.png 14 kB [emitted] dist/img/avatar3.png 9.78 kB [emitted] dist/img/avatar5.png 8.01 kB [emitted] dist/img/avatar2.png 8.84 kB [emitted] dist/img/credit/cirrus.png 1.59 kB [emitted] dist/img/credit/american-express.png 2.21 kB [emitted] dist/img/boxed-bg.png 43.7 kB [emitted] dist/img/boxed-bg.jpg 124 kB [emitted] vendor.bundle.js 11 kB 1 [emitted] vendor dist/img/credit/mastercard.png 1.59 kB [emitted] dist/img/credit/paypal.png 2.05 kB [emitted] dist/img/credit/paypal2.png 1.37 kB [emitted] dist/img/icons.png 1.15 kB [emitted] dist/img/user1-128×128.jpg 2.88 kB [emitted] dist/img/default-50×50.gif 184 bytes [emitted] dist/img/credit/visa.png 1.14 kB [emitted] dist/img/user5-128×128.jpg 6.45 kB [emitted] dist/img/user2-160×160.jpg 7.07 kB [emitted] dist/img/user4-128×128.jpg 3.48 kB [emitted] dist/img/user3-128×128.jpg 3.51 kB [emitted] dist/img/user6-128×128.jpg 4.34 kB [emitted] dist/img/user7-128×128.jpg 6.43 kB [emitted] dist/img/user8-128×128.jpg 5.06 kB [emitted] [207] (webpack)/buildin/module.js 521 bytes {0} [built] [237] (webpack)/buildin/global.js 823 bytes {0} [built] [303] ./src/index.js 467 bytes {0} [built] [392] ./src/App.js 15.3 kB {0} [built] [757] ./src/app.css 994 bytes {0} [built] [758] ./node_modules/css-loader!./src/app.css 439 bytes {0} [built] [762] multi react-hot-loader/patch ./src/adminlte_app.js 40 bytes {1} [built] [766] ./src/adminlte_app.js 22.6 kB {1} [built] + 759 hidden modules > [email protected] postbuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > npm run package > [email protected] package /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate > zip -r build.zip build/ adding: build/ (stored 0%) adding: build/dist/ (stored 0%) adding: build/dist/.DS_Store (deflated 97%) adding: build/dist/img/ (stored 0%) adding: build/dist/img/.DS_Store (deflated 97%) adding: build/dist/img/avatar.png (stored 0%) adding: build/dist/img/avatar04.png (stored 0%) adding: build/dist/img/avatar2.png (stored 0%) adding: build/dist/img/avatar3.png (stored 0%) adding: build/dist/img/avatar5.png (stored 0%) adding: build/dist/img/boxed-bg.jpg (deflated 7%) adding: build/dist/img/boxed-bg.png (deflated 0%) adding: build/dist/img/credit/ (stored 0%) adding: build/dist/img/credit/american-express.png (stored 0%) adding: build/dist/img/credit/cirrus.png (stored 0%) adding: build/dist/img/credit/mastercard.png (stored 0%) adding: build/dist/img/credit/mestro.png (stored 0%) adding: build/dist/img/credit/paypal.png (stored 0%) adding: build/dist/img/credit/paypal2.png (stored 0%) adding: build/dist/img/credit/visa.png (stored 0%) adding: build/dist/img/default-50×50.gif (deflated 7%) adding: build/dist/img/icons.png (deflated 2%) adding: build/dist/img/user1-128×128.jpg (deflated 5%) adding: build/dist/img/user2-160×160.jpg (deflated 3%) adding: build/dist/img/user3-128×128.jpg (deflated 5%) adding: build/dist/img/user4-128×128.jpg (deflated 0%) adding: build/dist/img/user5-128×128.jpg (deflated 2%) adding: build/dist/img/user6-128×128.jpg (deflated 3%) adding: build/dist/img/user7-128×128.jpg (deflated 2%) adding: build/dist/img/user8-128×128.jpg (deflated 3%) adding: build/index.html (deflated 68%) adding: build/index.js (deflated 69%) adding: build/vendor.bundle.js (deflated 67%) |