原来的项目用的roadhog,但是作者的重心转移到了umi导致一些依赖包迟迟不会更新.所以提出了移除roadhog的需求用webpack4代替.下面是详细的配置项
{
"name": "longhorn",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "webpack-dev-server --config=webpack.config.development.js --mode development",
"build": "cross-env NODE_ENV=production webpack --config=webpack.config.production.js --mode production",
"lint": "eslint --ext .js src",
"precommit": "npm run lint"
},
"dependencies": {
"@babel/runtime-corejs2": "^7.0.0",
"antd": "3.19.4",
"axios": "^0.19.0",
"classnames": "^2.2.5",
"cron-parser": "^2.11.0",
"dva": "^2.4.1",
"dva-loading": "^1.0.0",
"history": "^4.7.2",
"jquery": "^3.4.0",
"meteor-later": "^1.2.0",
"moment": "^2.10.6",
"nprogress": "0.2.0",
"prettycron": "^0.10.0",
"prop-types": "^15.7.2",
"qs": "^6.3.0",
"query-string": "^6.4.2",
"react": "^16.8.4",
"react-copy-to-clipboard": "^5.0.1",
"react-countup": "4.1.3",
"react-dom": "^16.8.4",
"react-helmet": "^5.0.0",
"react-resize-detector": "1.1.0",
"recharts": "^1.1.0",
"reconnecting-websocket": "^v3.2.2",
"semver": "^5.6.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@webassemblyjs/ast": "^1.3.1",
"@webassemblyjs/wasm-edit": "^1.3.1",
"acorn": "^6.1.1",
"add-asset-html-webpack-plugin": "^3.1.3",
"address": "^1.0.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^8.0.0",
"babel-plugin-dva-hmr": "^0.4.1",
"babel-plugin-import": "^1.7.0",
"babel-plugin-transform-remove-console": "^6.9.2",
"body-parser": "^1.18.3",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.1",
"cross-env": "^5.1.1",
"cross-port-killer": "^1.0.1",
"css-hot-loader": "^1.4.4",
"css-loader": "^2.1.1",
"cssnano": "^4.1.10",
"es5-imcompatible-versions": "^0.1.34",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-compat": "^2.2.0",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.7.0",
"estraverse": "^4.2.0",
"expect": "^1.20.2",
"file-loader": "^1.1.11",
"friendly-errors-webpack-plugin": "^1.7.0",
"happypack": "^5.0.0-beta.4",
"html-webpack-plugin": "^3.2.0",
"husky": "^1.0.0-rc.4",
"keymaster": "^1.6.2",
"less": "^3.0.4",
"less-loader": "^4.1.0",
"mini-css-extract-plugin": "^0.4.0",
"mockjs": "^1.0.1-beta3",
"open-browser-webpack-plugin": "0.0.5",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"pre-commit": "^1.2.2",
"pro-download": "^1.0.1",
"progress-bar-webpack-plugin": "^1.12.1",
"redbox-react": "^1.5.0",
"redux-devtools": "^3.4.1",
"redux-devtools-dock-monitor": "^1.1.3",
"redux-devtools-log-monitor": "^1.4.0",
"regenerator-runtime": "^0.11.1",
"sass-loader": "^7.0.1",
"serve-index": "^1.9.1",
"string-replace-loader": "^2.1.1",
"style-loader": "^0.21.0",
"type-is": "^1.6.15",
"uglifyjs-webpack-plugin": "^1.2.5",
"url-loader": "^1.0.1",
"webpack": "^4.33.0",
"webpack-cli": "^3.1.1",
"webpack-dev-server": "^3.1.4",
"webpack-manifest-plugin": "^2.0.4"
},
"pre-commit": [
"precommit"
]
}
dev
/* eslint-disable */
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ManifestPlugin = require("webpack-manifest-plugin");
const theme = require("./src/theme");
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
var FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const endpoint = process.env.LONGHORN_MANAGER_IP || 'http://54.223.25.181:9500/';
module.exports = {
entry: path.resolve(__dirname, "src", "index.js"),
devServer: {
// contentBase: path.resolve(__dirname, 'dist'),
host: "0.0.0.0",
port: 8080,
open: false,
hot: true,
quiet: true,
historyApiFallback: true,
overlay: {
errors: true
},
stats: {
children: false,
chunks: false,
assets: false,
modules: false
},
proxy: {
proxyTimeout: 10 * 60 * 1000,
timeout: 10 * 60 * 1000,
"/v1/ws/**": {
"target": endpoint,
"changeOrigin": false,
"ws": true,
"secure": false
},
"/v1/": {
"target": endpoint,
"changeOrigin": false
},
}
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
publicPath: "/",
chunkFilename: "[name].async.js",
library: "[name]_dll"
},
resolve: {
alias: {
components: path.resolve(__dirname, "src/components/"),
layouts: path.resolve(__dirname, "src/layouts/"),
utils: path.resolve(__dirname, "src/utils/"),
services: path.resolve(__dirname, "src/services/"),
routes: path.resolve(__dirname, "src/routes/"),
models: path.resolve(__dirname, "src/models/")
}
},
module: {
rules: [
{
test: /\.js$/,
include: [path.resolve(__dirname, "src")],
exclude: [],
loader: "babel-loader?cacheDirectory",
},
{
test: /\.css$/,
use: [
{
loader: "css-loader",
options: {
importLoaders: 1
}
}
]
},
{
test: /\.less$/,
use: [
'css-hot-loader',
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true,
// if hmr does not work, this is a forceful method.
reloadAll: true,
modifyVars: theme()
},
},
{
loader: "css-loader",
options: {
sourceMap: true,
importLoaders: 1,
modules: true,
localIdentName: "[name]_[local]-[hash:base64:5]"
}
},
{
loader: "less-loader",
options: {
sourceMap: true,
javascriptEnabled: true,
modifyVars: theme()
}
}
],
exclude: /node_modules/
},
{
test: /\.less$/,
use: [
'css-hot-loader',
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true,
// if hmr does not work, this is a forceful method.
reloadAll: true,
modifyVars: theme()
},
},
{
loader: "css-loader",
options: {
sourceMap: true,
importLoaders: 1
}
},
{
loader: "less-loader",
options: {
sourceMap: true,
javascriptEnabled: true,
modifyVars: theme()
}
}
],
exclude: /src/
},
{
test: /\.(ttf|eot|svg|woff|woff2|png|svg|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192
}
}
]
}
]
},
externals: {
jquery: "jQuery"
},
node: {
fs: "empty",
module: "empty"
},
devtool: "source-map",
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
test: /\.(css|less)/,
chunks: "all",
enforce: true
}
}
}
},
plugins: [
new OpenBrowserPlugin({url: 'http://localhost:8080/'}),
new ProgressBarPlugin(),
new FriendlyErrorsWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: '[id].css'
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.ejs"),
filename: "index.html",
hash: true
}),
new CleanWebpackPlugin(["dist"]),
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, "public")
}
]),
new webpack.HotModuleReplacementPlugin(),
new ManifestPlugin()
]
};
production
/* eslint-disable */
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const HappyPack = require("happypack");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const ManifestPlugin = require("webpack-manifest-plugin");
const os = require("os");
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
const theme = require("./src/theme");
module.exports = {
entry: path.resolve(__dirname, "src", "index.js"),
output: {
filename: "[name].[chunkhash:8].js",
path: path.resolve(__dirname, "dist"),
publicPath: "/",
chunkFilename: "[name].[chunkhash:8].async.js"
},
resolve: {
alias: {
components: path.resolve(__dirname, "src/components/"),
layouts: path.resolve(__dirname, "src/layouts/"),
utils: path.resolve(__dirname, "src/utils/"),
services: path.resolve(__dirname, "src/services/"),
routes: path.resolve(__dirname, "src/routes/"),
models: path.resolve(__dirname, "src/models/")
}
},
module: {
rules: [
{
test: /\.js$/,
include: [path.resolve(__dirname, "src")],
exclude: /node_modules/,
use: ["happypack/loader?id=babel"]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1
}
}
]
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
// sourceMap: true,
importLoaders: 1,
modules: true,
localIdentName: "[name]_[local]-[hash:base64:5]"
}
},
{
loader: "less-loader",
options: {
// sourceMap: true,
javascriptEnabled: true,
modifyVars: theme()
}
}
],
exclude: /node_modules/
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
// sourceMap: true,
importLoaders: 1
}
},
{
loader: "less-loader",
options: {
// sourceMap: true,
javascriptEnabled: true,
modifyVars: theme()
}
}
],
exclude: /src/
},
{
test: /\.(ttf|eot|svg|woff|woff2|png|svg|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192
}
}
]
}
]
},
stats: {
children: false
},
performance: {
hints: false
},
externals: {
jquery: "jQuery"
},
node: {
fs: "empty",
module: "empty"
},
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
test: /\.(css|less)/,
chunks: "all",
enforce: true
},
commons: {
name: "commons",
chunks: "initial",
minChunks: 2
},
vendors: {
name: "vendors",
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
},
runtimeChunk: true
},
plugins: [
new ProgressBarPlugin(),
new ManifestPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css"
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.ejs"),
filename: "index.html",
hash: true
}),
new CleanWebpackPlugin(["dist"]),
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, "public")
}
]),
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require("cssnano"),
cssProcessorOptions: { discardComments: { removeAll: true } },
canPrint: true
}),
new HappyPack({
id: "babel",
loaders: ["babel-loader?cacheDirectory"],
threadPool: happyThreadPool
}),
new webpack.HashedModuleIdsPlugin()
]
};
babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"import",
{
"libraryName": "antd",
"libraryDirectory": "es",
"style": true
}
],
"@babel/plugin-proposal-class-properties",
[
"@babel/plugin-transform-runtime",
{
"corejs": 2
}
],
"dva-hmr",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta",
"@babel/plugin-proposal-json-strings",
"@babel/plugin-proposal-function-sent",
"@babel/plugin-proposal-export-namespace-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-throw-expressions",
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-logical-assignment-operators",
"@babel/plugin-proposal-optional-chaining",
[
"@babel/plugin-proposal-pipeline-operator",
{
"proposal": "minimal"
}
],
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-proposal-function-bind"
],
"env": {
"production": {
"plugins": [
"transform-remove-console",
"@babel/plugin-syntax-dynamic-import"
]
}
}
}
这些是基础的配置 详细的可以看这两个pr
https://github.com/longhorn/longhorn-ui/pull/167/files
下面的pr加入了css的hmr
https://github.com/longhorn/longhorn-ui/pull/168/files
如果有帮助请赏我个start