目录结构如下:
package.json:
{
"name": "react-webpack-cms",
"version": "1.0.0",
"description": "",
"main": "src/index.tsx",
"scripts": {
"build-dev": "cross-env NODE_ENV=development webpack --config ./bin/webpack.dev.config.js --colors",
"build-proc": "cross-env NODE_ENV=production webpack --config ./bin/webpack.proc.config.js --colors",
"dev":"cross-env NODE_ENV=development node ./bin/dev-server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/react": "^16.4.12",
"@types/react-dom": "^16.0.7",
"react": "^16.4.2",
"react-dom": "^16.4.2"
},
"devDependencies": {
"autoprefixer": "^9.1.3",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^2.0.0",
"fs": "^0.0.1-security",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.9.3",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"source-map-loader": "^0.2.4",
"style-loader": "^0.23.0",
"ts-loader": "^4.5.0",
"uglifyjs-webpack-plugin": "^1.3.0",
"webpack": "^4.17.1",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.6",
"webpack-merge": "^4.1.4"
}
}
tsconfig.json:
{
"version": "2.5.3",
"compilerOptions": {
"jsx": "react",
"module": "commonjs",
"target": "es5",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outDir": "dist",
"sourceMap": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
index.html:
title
index.tsx:
import * as React from "react"
import * as ReactDOM from "react-dom"
ReactDOM.render(
Hello world,
document.getElementById('app')
);
// console.log(1);
GetEAP.js获取plugins:
const path = require('path');
const webpack = require('webpack');
const __DEV__ = process.env.NODE_ENV !== 'production';
/**
* extract-text-webpack-plugin插件
* TODO: 将样式提取到单独的css文件中不将css打包到js中
*/
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
/**
* html-webpak-plugin插件,生成html插件
* TODO: https://www.npmjs.com/package/html-webpack-plugin
*/
const HtmlWebpackPlugin = require('html-webpack-plugin');
/**
* clean-webpack-plugin插件
* TODO: 热更新删除打包的文件
*/
const CleanWebpackPlugin = require('clean-webpack-plugin');
/**
* TODO: getPlugins
*/
class getPlugins {
constructor() {
var plugins = [
new webpack.optimize.RuntimeChunkPlugin({
name: "manifest"
}),
new ExtractTextWebpackPlugin('static/css/[name].css'),
new HtmlWebpackPlugin({
favicon: path.join(__dirname, '..', 'static', 'favicon.ico'),
filename: 'index.html',
template: './src/index.html',
inject: 'body',
hash: true,
chunks: ['main', 'manifest', 'vendor'],
minify: {
removeComments: true,
collapseWhitespace: false
}
}),
new webpack.HotModuleReplacementPlugin(),
];
if (!__DEV__) {
plugins.push(new CleanWebpackPlugin('dist/', {
root: path.join(__dirname, '..'),
verbose: true,
dry: false
}));
}
return plugins;
}
}
module.exports = getPlugins;
webpack.base.config.js:
const __DEV__ = process.env.NODE_ENV !== 'production';
const path = require('path');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const GetEAP = require('../lib/GetEAP');
const config = require('../lib/config');
module.exports = {
mode: __DEV__ ? 'development' : 'production',
entry: [path.resolve(__dirname, '..', 'src', 'index.tsx')],
output: {
path: path.resolve(__dirname, '..', 'dist'),
publicPath: __DEV__ ? config.dev.assertPublicPath : config.proc.assertPublicPath,
},
module: {
rules: [{
test: /\.(css|scss)$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
// options: {
// minimize: true
// }
}, 'postcss-loader', 'sass-loader']
})
}, {
test: /\.html$/,
loader: 'html-loader?attrs=img:src img:data-src',
}, {
test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader?limit=1024&name=static/fonts/[name].[ext]'
}, {
test: /\.js$/,
use: ['babel-loader', 'source-map-loader'],
exclude: /node_modules/
}, {
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}]
},
plugins: new GetEAP(),
node: {
fs: 'empty'
},
};
webpack.dev.config.json:
const merge = require('webpack-merge');
const webpackBaseConfig = require('./webpack.base.config');
const path = require('path');
const config = require('../lib/config');
module.exports = merge(webpackBaseConfig, {
output: {
path: path.join(__dirname, '..', 'dist'),
publicPath: config.dev.assertPublicPath,
filename: 'static/js/[name].js',
hotUpdateChunkFilename: './static/hot/hot-update.js',
hotUpdateMainFilename: './static/hot/hot-update.json'
},
devtool: 'source-map',
resolve: {
extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.jsx']
},
});
webpack.proc.config.json:
const merge = require('webpack-merge');
const path = require('path');
const webpackBaseConfig = require('./webpack.base.config');
const config = require('../lib/config');
module.exports = merge(webpackBaseConfig, {
output: {
path: path.resolve(__dirname, '..', 'dist'),
publicPath: config.proc.assertPublicPath,
filename: 'static/js/[name].[hash].min.js',
},
});
config.js
module.exports = {
dev: {
assertPublicPath: './',
port: '8080'
},
proc: {
assertPublicPath: './',
}
};
git地址:http://git.lwwin.cn/liangwei/webpack-react-cms.git