手动搭建一个webpack+react笔记
{ "name": "lottery", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "", "dev": "node ./build/dev.server.js", "build": "rimraf ./dist && webpack --config ./config/pro.config.js -p", "mock": "cross-env NODE_ENV=mock node ./build/dev.server.js" }, "author": "", "license": "ISC", "dependencies": { "history": "^4.6.1", "mobx": "^3.2.2", "mobx-react": "^4.2.2", "prop-types": "^15.5.8", "react": "^15.5.4", "react-dom": "^15.5.4", "react-redux": "4.4.8", "react-router": "^4.1.1", "react-router-dom": "^4.1.1", "react-router-redux": "^5.0.0-alpha.6", "react-transition-group": "^1.1.3", "redux": "^3.6.0", "whatwg-fetch": "^2.0.3" }, "devDependencies": { "autoprefixer": "^6.7.7", "babel-core": "^6.24.1", "babel-eslint": "^7.2.2", "babel-loader": "^6.4.1", "babel-plugin-react-transform": "^2.0.2", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-runtime": "^6.23.0", "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.24.1", "babel-preset-react": "^6.24.1", "babel-preset-react-hmre": "^1.1.1", "babel-preset-stage-0": "^6.24.1", "bundle-loader": "^0.5.5", "copy-webpack-plugin": "^4.0.1", "cross-env": "^5.0.0", "css-loader": "^0.28.0", "eslint": "^3.19.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^2.0.7", "eslint-loader": "^1.7.1", "eslint-plugin-html": "^2.0.1", "eslint-plugin-import": "^2.2.0", "eslint-plugin-node": "^4.2.2", "eslint-plugin-promise": "^3.5.0", "eslint-plugin-react": "^6.10.3", "eslint-plugin-standard": "^3.0.1", "express": "^4.15.2", "extract-text-webpack-plugin": "^2.1.0", "file-loader": "^0.11.2", "html-webpack-plugin": "^2.28.0", "http-proxy-middleware": "^0.17.4", "less": "^2.7.2", "less-loader": "^4.0.3", "mockjs": "^1.0.1-beta3", "node-sass": "^4.5.2", "open": "0.0.5", "postcss-loader": "^1.3.3", "rimraf": "^2.6.1", "sass-loader": "^6.0.3", "style-loader": "^0.16.1", "url-loader": "^0.5.8", "webpack": "^2.4.1", "webpack-dev-middleware": "^1.10.1", "webpack-hot-middleware": "^2.18.0", "webpack-merge": "^4.1.0" } }
首先这是需要安装的包
然后看dev.server里的代码
const express = require("express") const webpackDevMiddleware = require("webpack-dev-middleware") const webpack = require("webpack") let webpackConfig = require("../config/dev.config") const path = require('path') let config = require('../config') const app = express() const open = require('open') process.env.NODE_ENV === 'mock' && require('../mock/data')(app) require('../config/proxy')(app) // 代理 let compiler = webpack(webpackConfig) app.use(require("webpack-hot-middleware")(compiler));//固定写法 app.use(path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory), express.static('./static')) // 当所有/static这个下的请求
都转到static目录 app.use(webpackDevMiddleware(compiler, { publicPath: config.dev.assetsPublicPath })) app.listen(config.dev.port, function (res) { console.log(`Listening on port ${config.dev.port}!`) process.env.NODE_ENV !== 'mock' && open(`http://localhost:${config.dev.port}/#/index`) })
之所以叫简版,是因为去除了一些花哨或者用处不大的东西,比如运行命令行的颜色,以及进度百分比等等
首先要搭建,必然需要一个服务器,这里为什么不选自带的webpack-dev-server,因为webpack-dev-server定制性差,比如我要改个端口,要在script里面改不能变量,
所以这里选择express做服务器,
webpack-dev-middleware是webpack为expres服务器提供的中间件,再说白了,就是让express的服务器支持热更新和缓存的(配合webpack-hot-middleware)
然后是proxy里的代码
const proxy = require('http-proxy-middleware') const preA = require('./http_prefix').preA const tables = [{ proxy: preA, target: '' }] module.exports = (app) => { for (let i = 0; i < tables.length; i ++) { app.use(tables[i].proxy, proxy({ target: tables[i].target, changeOrigin: true })) } } // 遍历代理的接口
然后我们看下config下面的index.js文件是什么以及dev.config文件是什么
const path = require('path') const webpack = require('webpack') const merge = require('webpack-merge') const base = require('./base.config') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = merge({ entry: ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000','babel-polyfill','./src/main.js'], //需要热更新的配置 output: { path: '/',这个这里作用不大build时候作用对应文件位置 filename: '[name].js' }, module: { rules: [ { test: /\.less$/, loaders: ['style-loader','css-loader?modules&localIdentName=[local]-[hash:base64:5]', 'less-loader', 'postcss-loader'] }, { test: /\.scss$/, loaders: ['style-loader','css-loader', 'sass-loader', 'postcss-loader'] }, ] }, plugins: [ new webpack.LoaderOptionsPlugin({ options: { eslint: { formatter: require('eslint-friendly-formatter') } } }), new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true // 打包好的js文件是插入到body还是body尾部 }) ], devtool: 'eval-source-map', }, base)
const path = require('path') module.exports = { build: { assetsSubDirectory: 'static', assetsPublicPath: '/', assetsRoot: path.resolve(__dirname, '../dist') }, dev : { assetsSubDirectory: 'static', assetsPublicPath: '/', port: 3020, } } 就是一些当本地运行或者生产时候对应的配置