package.js
{
"name": "lesson",
"sideEffects": [
"*.css"
],
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev-build": "webpack --config ./build/webpack.dev.js",
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js",
"build:dll": "webpack --config ./build/webpack.dll.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.2.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
"autoprefixer": "^9.3.1",
"babel-loader": "^8.0.4",
"clean-webpack-plugin": "^1.0.0",
"css-loader": "^1.0.1",
"express": "^4.16.4",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"imports-loader": "^0.8.0",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.4.0",
"webpack-dev-server": "^3.1.10",
"webpack-merge": "^4.1.5"
},
"dependencies": {
"@babel/polyfill": "^7.0.0",
"@babel/runtime": "^7.2.0",
"@babel/runtime-corejs2": "^7.2.0",
"add-asset-html-webpack-plugin": "^3.1.2",
"jquery": "^3.3.1",
"lodash": "^4.17.11",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"webpack": "^4.25.1"
}
}
postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
}
.babelrc
{
presets: [
[
"@babel/preset-env", {
targets: {
chrome: "67",
},
useBuiltIns: 'usage'
}
],
"@babel/preset-react"
],
plugins: ["@babel/plugin-syntax-dynamic-import"]
}
./build/webpack.common.js
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
const webpack = require('webpack');
const makePlugins = (configs) => {
const plugins = [
new CleanWebpackPlugin(['dist'], {
root: path.resolve(__dirname, '../')
})
];
Object.keys(configs.entry).forEach(item => {
plugins.push(
new HtmlWebpackPlugin({
template: 'src/index.html',
filename: `${item}.html`,
chunks: ['runtime', 'vendors', item]
})
)
});
const files = fs.readdirSync(path.resolve(__dirname, '../dll'));
files.forEach(file => {
if(/.*\.dll.js/.test(file)) {
plugins.push(new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, '../dll', file)
}))
}
if(/.*\.manifest.json/.test(file)) {
plugins.push(new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, '../dll', file)
}))
}
});
return plugins;
}
const configs = {
entry: {
index: './src/index.js',
list: './src/list.js',
detail: './src/detail.js',
},
resolve: {
extensions: ['.js', '.jsx'],
},
module: {
rules: [{
test: /\.jsx?$/,
include: path.resolve(__dirname, '../src'),
use: [{
loader: 'babel-loader'
}]
}, {
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
limit: 10240
}
}
}, {
test: /\.(eot|ttf|svg)$/,
use: {
loader: 'file-loader'
}
}]
},
optimization: {
runtimeChunk: {
name: 'runtime'
},
usedExports: true,
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors',
}
}
}
},
performance: false,
output: {
path: path.resolve(__dirname, '../dist')
}
}
configs.plugins = makePlugins(configs);
module.exports = configs
./build/webpack.dev.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const devConfig = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true
},
module: {
rules: [{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
}, {
test: /\.css$/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: '[name].js',
chunkFilename: '[name].js',
}
}
module.exports = merge(commonConfig, devConfig);
./build/webpack.dll.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
mode: 'production',
entry: {
vendors: ['lodash'],
react: ['react', 'react-dom'],
jquery: ['jquery']
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, '../dll'),
library: '[name]'
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: path.resolve(__dirname, '../dll/[name].manifest.json'),
})
]
}
./build/webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const prodConfig = {
mode: 'production',
devtool: 'cheap-module-source-map',
module: {
rules:[{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
}, {
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}]
},
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].chunk.css'
})
],
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].js'
}
}
module.exports = merge(commonConfig, prodConfig);