使用 webpack 手动搭建 react脚手架
创建项目文件夹 并执行
安装 开发依赖
- -D 意思是开发模式下需要的插件,安装webpack 相关依赖
npm i -D webpack webpack-cli webpack-dev-server
- 安装 babel 相关依赖,也就是解析jsx语法所需要的
npm i -D babel-loader @babel/preset-react @babel/preset-env @babel/core
- 安装 css 加载器,如果你要使用less等语法当然需要额外安装和在 webpack.config做对应配置
npm i -D style-loader css-loader
- 安装 必要的打包插件 ,具体作用详见 webpack.config
npm i -D html-webpack-plugin copy-webpack-plugin mini-css-extract-plugin
npm i -D cross-env
安装react
npm i --save react react-dom
修改package.json的 scripts节点
"scripts": {
"start": "cross-env NODE_ENV=development node index.js",
"build": "cross-env NODE_ENV=production webpack -p --progress --profile --colors --config webpack.config.js"
}
创建配置文件 webpack.config.js
const webpack = require('webpack');
const path = require("path");
// webpack插件
// (html打包插件)
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 复制插件 用于 public 内容的拷贝
const CopyPlugin = require('copy-webpack-plugin');
// css 打包插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const outputPath = path.join(__dirname, './dist'); // 打包输出路径
module.exports = {
mode: process.env.NODE_ENV || 'development', // 模式就是执行环境
entry: {
main: './src/app.js' // 启动入口
},
output: { // 打包输出配置
path: outputPath, // 输出位置
filename: '[name].js', // 打包文件名生成规则 [name]表示直接使用文件名生成 ,[name]_[hash:10].js 表示在文件名后面拼接10位长度的hash作为新的文件名
publicPath: '/' // public path,打包出来的html,所有资源的路径
},
plugins: [ // webpack 打包插件配置
new CopyPlugin([ // 拷贝插件
{from: path.join(__dirname, './public') , to: outputPath} // 将 public下面的文件 拷贝到 输出路径也就是 dist下
]),
new HtmlWebpackPlugin({ // index.html 打包插件
template: path.resolve(__dirname, 'public','index.html'), // 代码模版在 public/index.html
title: 'AWKO', // 配置网页标题
}),
new MiniCssExtractPlugin({filename: "[name].css", chunkFilename: "[name][id].css"}), // 同样的进行 css文件名的 hash
new webpack.HotModuleReplacementPlugin() // webpack 的 热刷新插件
],
module: { // 模块配置
rules: [ // 匹配对应文件 调用对应的语法糖 加载器
{
test: /\.js[x]?$/, // 匹配正则,意思是文件名以 .js 或者 .jsx结尾的文件
include: path.join(__dirname,'src'), // 匹配的文件路径,这里是匹配 src 下面的文件
loader: 'babel-loader', // 这是配置加载器,此处是 babel-loader 也就是jsx语法糖的加载器
query: { // babel-loader 需要的一些 参数
"presets": ["@babel/react", "@babel/env",]
}
},
{
test: /\.css$/, // .css 的加载器
use: [
require.resolve('style-loader'), {
loader: require.resolve('css-loader'),
options: {
importLoaders: 1
}
}
]
},
/* 如果你有用 .less 或者 sass 等 ,下面可以配置对应的文件加载器 */
]
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/, // 这里的效果是把所有的 node_modules的代码全部压缩打包为 vendors.js
name: 'vendors',
chunks: 'all'
}
}
}
},
resolve: {
// module搜索路径
modules: [
"node_modules",
path.resolve(__dirname, "src")
],
extensions: [".js", ".json", ".jsx", ".css"]
},
devtool: 'source-map', // 开发工具,source-map 可以在 网页运行时看到代码日志对应的位置,而不是全是压缩过后的代码
devServer:{ // 这里也不太理解
contentBase: outputPath,
hot: true,
}
}
创建文件夹 src, public
public 中创建 index.html 作为模版,并创建 index.css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
<div id="app">
<div class="loading">
Loading...
</div>
</div>
</body>
</html>
html, body {
margin: 0px;
width: 100%;
}
.loading {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
src 中 创建 app.js 也就是 react代码入口
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<div>HELLO WEBPACK</div>
, document.getElementById("app"));
在根目录创建 index.js 也就是 npm run start 的服务
// 配置
const webpackConfig = require("./webpack.config.js");
const webpack = require('webpack');
const path = require("path");
// webpack 开发模式的 服务器插件
const WebpackDevServer = require('webpack-dev-server');
const serverHost = '127.0.0.1';
const serverPort = 3000;
var options = {
contentBase: path.resolve(__dirname, "src/static"), // 不太理解
hot: true, // 打开热更
host: serverHost, // 这个地方监听的服务地址
compress: true,
historyApiFallback:true,
stats: {
colors: true,
errors: true,
warnings: true,
modules: false, // 输出modules编译
chunks: false,
},
proxy: [
{
context: ["/api"], // 需要代理的 网络请求的 匹配规则
target: 'http://yourserver.com', // 这里是配置代理的服务器
secure: false,
onProxyReq: (proxyReq, req, res) => {
proxyReq.setHeader('host', 'yourserver.com'); // 这里是代理服务器的域名
}
}
]
};
WebpackDevServer.addDevServerEntrypoints(webpackConfig, options);
const compiler = webpack(webpackConfig);
const server = new WebpackDevServer(compiler, options);
server.listen(serverPort); // 服务开始监听,指定监听端口