This article is reproduced in front-end _Logic's blog.
Original address: http://blog.csdn.net/lx376693576/article/details/54591142
Written in: 2017-1-18
Complete and clean demo address: coding.net/u/java_luo/p/react_luo/git
Technology stack:
react, redux, webpack, eslint, babel, antd
1. Pre-preparation
(1) windows system. This framework is configured under windows system.
SublimeText, the editor used
II. Installation Node.js
(3) Create a folder, use node command line tool to enter the folder, run npm init command to generate an initial package.json
2. Configuring package.json
{
"name": "myreact", // Project name
"version": "1.0.0", // Project version
"description": "...", // Project brief introduction
"main": "index.js", // Project entrance js, no need to write one here when decorating
"scripts": {
"watch": "node server.js", // Run this command in development mode to start the service
"build": "webpack -p --config webpack.production.config.js --progress --profile --colors" // The final package of the project runs this command (webpack.production.config.js is the webpack configuration file to be created later)
},
"author": "luo", // Project author
"license": "ISC", // Project Open Source License
"private": true, // Is the project private?
// Plug-ins that the project ultimately needs to rely on
"dependencies": {
"antd": "^2.6.3", // ui Library of ant golden clothes
"babel-polyfill": "^6.20.0", // Used to parse various new functions of ES6 (such as map,set,Generator, etc.)
"react": "^15.4.2", // react framework core
"react-dom": "^15.4.2", // Reaction rendering components are used
"react-redux": "^5.0.1", // Bridge between react and redux
"react-router": "^3.0.0", // react router, used for routing
"react-router-redux": "^4.0.7", // Bridge between react routing and redux
"redux": "^3.6.0", // redux core
"redux-thunk": "^2.1.0", // redux middleware for handling asynchronous action s
"reqwest": "^2.0.5" // A tool plug-in encapsulating fetch, useful for asynchronous requests
},
// Dependent plug-ins in development mode
"devDependencies": {
"babel-core": "^6.21.0", // babel core
"babel-loader": "^6.2.10", // Web pack parser: Used to parse ES6 when packaging
"babel-plugin-import": "^1.1.0", // On-demand loading, for the ant golden clothes ui library, which ui components are used, compile which components
"babel-preset-es2015": "^6.18.0", // babel plug-in: parsing ES6 syntax
"babel-preset-react": "^6.16.0", // babel plug-in: parsing react grammar (JSX)
"babel-preset-stage-3": "^6.17.0", // babel plug-in: parsing some of the syntax of the latest version of js
"css-loader": "^0.26.1", // webpack parser: when packaging, url path problems in files such as css, less, and sass, such as background-image path, automatically match the root path of the project
"eslint": "^3.13.1", // A grammar checker, often used in development to standardize code style and troubleshooting
"eslint-loader": "^1.6.1", // Webpack parser: add eslint to webpack, so you need this
"eslint-plugin-react": "^6.9.0", // eslint plug-in: supports checking react syntax
"extract-text-webpack-plugin": "^1.0.1", // When the project is finally packaged, pack all the style files into a single css file. You need this
"file-loader": "^0.9.0", // webpack parser: parse all kinds of non-picture files and gif files when packaging
"html-webpack-plugin": "^2.26.0", // webpack plug-in: automatically generate an index.html when packaging
"less": "^2.7.2", // less core
"less-loader": "^2.2.3", // webpack parser: parse less when packaged
"style-loader": "^0.13.1", // webpack parser: add style files to pages when packaging, and automatically generate < style > tags
"url-loader": "^0.5.7", // Web pack parser: Processing pictures or other files will compile small pictures into base64 encoding
"webpack": "^1.14.0", // Web pack modular packaging tool
"webpack-dev-server": "^1.16.2" // A server tool used in conjunction with webpack to start a service after packaging is completed, making it easy for developers to test, equivalent to tomcat
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
3. Then create the basic directory structure of the project
There are two things in the diagram that are not used directly, but are loaded into the web pack and called automatically when the web pack is packaged:
(1). babelrc, that is, babel function is to let webpack to call.
(2),.eslintrc.json, that is, grammar checking is automatically checked when packaged.
4. Configuring babel
babel is used to parse ES6, jsx and other new grammars so that modern browsers can run.
Create a. babelrc file (named. babelrc, no suffix)
{
// Using three plug-ins of babel, es2015,stage-3,react (that is, the three plug-ins of npm install)
"presets": ["es2015", "stage-3", 'react'],
// Below is the configuration for loading that plug-in on demand (babel-plugin-import)
// It's copied from Ant Gold, which basically means that css, less and other style files need to be loaded on demand.
// js also needs to be loaded on demand
"plugins": [["import",[
{
"libraryName": "antd",
"libraryDirectory": "lib",
"style": true
},
{
"libraryName": "antd-mobile",
"libraryDirectory": "component",
},
]]]
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
5. Configuring eslint
{
// Project environment
// This means that the following configurations of these environments, their own global variables, are considered to exist by eslint, such as jquery's $, and if jquery:true is not configured below and $is used directly in the project, eslint will assume that $is undefined.
"env": {
"browser": true, // Browser environment, window s variables, etc.
"commonjs": true, // commonjs environment, require method, etc.
"es6": true, // es6 environment, various new functions of es6
"jquery": true // jquery is the symbol of $
},
// Inheritance of an officially defined inspection rule
// Here's the rule of react, which must be matched, otherwise eslint can't recognize react
"extends": "plugin:react/recommended",
// Setting up various parsers
"parserOptions": {
"ecmaVersion": 8, // js version, the latest 8 (JS2017)
"ecmaFeatures": { // Additional language features
"impliedStrict": true, // Global Enabling Strict Mode
"experimentalObjectRestSpread": true, // Supports the... Remainder operator, which is the'...'deconstruction assignment in ES6
"jsx": true // jsx syntax
},
"sourceType": "module" // Code type: Modularization. Because we often use import,export, etc.
},
// Third-party plug-ins
"plugins": [
"react" // Support react (eslint-plugin-react), which is configured with jsx, but the react syntax is not just jsx, so you need this
],
// Customized inspection rules
"rules": {
// The quotation marks of strings must be single quotation marks
"quotes": [
"error",
"single"
],
// A semicolon must be added at the end of each sentence of code
"semi": [
"error",
"always"
],
"no-cond-assign": "error", // Prohibit the occurrence of assignment operators in conditional expressions
"no-debugger": "error", // debugger is not allowed in code
"no-dupe-args": "error", // function forbids renaming parameters
"no-caller": "error", // Disable arguments.caller or arguments.callee
"no-invalid-this": "error", // Prohibit global this
"no-unmodified-loop-condition": "error", // Prohibit Dead Cycle
"no-with": "error", // Prohibit the use of with statements
"no-catch-shadow": "error" // The parameter of the forbidden catch clause has the same name as the variable in the outer scope
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
The specific usage and configuration of eslit can be consulted from this website: Eslint Chinese Station
6. Configuring webpack
Web pack is used for project packaging, which compresses many js,css and other files, confuses encryption, and finally generates only a few merged files.
The configuration of development environment and production environment is different. The following is the configuration of development environment:
webpack.dev.config.js
var path = require('path'); // Used to get the root path
var webpack = require('webpack'); // webpack core
var ROOT_PATH = path.resolve(__dirname); // Project Root Path
var APP_PATH = path.resolve(ROOT_PATH, 'src'); // src directory path of project
var APP_FILE = path.resolve(APP_PATH, 'app'); // The entry file for the project (src/app.js)
var BUILD_PATH = path.resolve(ROOT_PATH, '/build'); //Packed files are required to be stored in this directory (in development mode, we are generally configured to eventually generate a bundle.js)
module.exports = {
/* Files that need to be packaged are configured here */
entry: {
app: [
'webpack-dev-server/client?http://localhost:8888', // Hot update listens for this address (the port number is the same as the configuration in server.js, we'll write server.js later)
'webpack/hot/only-dev-server', // Enable Hot Update
APP_FILE // Entry file
]
},
/* Files to be exported after packaging are configured here */
output: {
publicPath: '/test/', // This is when starting webpack-dev-server, the reference path of bundle.js should be relative to this path, that is, in index.html:
// <script src="/test/bundle.js"></script>
// And for all url addresses, such as background images in css, the src of img in html automatically becomes: / test /*****
path: BUILD_PATH, // Placing packaged files in this path will only exist in memory in development mode, and will not generate real files in this path.
filename: 'bundle.js', //Final Generated File Name
},
devtool: 'source-map', // After packaging, the code is compressed. If the error can't be seen in which line, the configuration is to solve this problem.
/* Here are some parsers to configure */
module: {
/* Run before packing */
preLoaders: [
{
test: /\.js?$/, // Parse. js,.jsx
loader: 'eslint', // The parser is eslint, which checks the grammar, but it will report errors if it clears.
exclude: /node_modules/, // Do not check the contents in the node_modules directory
},
],
/* Parsers needed for packaging */
loaders: [
// Parse. js,.jsx. With the babel parser, webpack will automatically load the. babelrc file we configured.
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
},
// Parse. css, first execute css-loader, then style-loader
// Note: Even the node_modules are parsed
{
test: /\.css$/,
loaders: ['style', 'css'],
},
// Parse. less, first execute css-loader, then style-loader
// Note: Even the node_modules are parsed (because the style files of the Ant Golden Wear ui framework exist in this directory)
// If you don't use less, you don't need to match (if you don't, you need to use antd.css instead of antd.less for the style file of the Ant Golden Wear ui framework)
{
test: /\.less$/,
loaders: ['style', 'css', 'less'],
},
// Other types of file processing, packaged will move these files to a packaged folder
{
test: /\.(eot|woff|svg|ttf|woff2|gif|appcache|mp3)(\?|$)/,
exclude: /node_modules/,
loader: 'file-loader?name=[name].[ext]',
},
// Processing pictures, the configuration here is that pictures less than 8192 bytes become base64 encoding, the rest of the pictures will eventually generate an image folder, stored in it.
{
test: /\.(png|jpg|gif)$/,
exclude: /node_modules/,
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]',
}
]
},
/* Configure some additional webpack plug-ins */
plugins: [
new webpack.HotModuleReplacementPlugin(), // Hot Update Plug-in
new webpack.NoErrorsPlugin() // Running without interruption even if there are errors
],
/* Configure additional custom solutions */
resolve: {
extensions: ['', '.js', '.jsx', '.less', '.css'], //When web packages are packaged, files with these suffix names are automatically matched
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
In the development mode:
(1) All style files are added to the head of index.html in an embedded way.
(2) A bunde.js file only exists in memory will be generated.
7. Write server.js
Step 6 configures webpack.dev.config.js. After packaging, you need to run the project.
So write a server.js:
var webpack = require('webpack'); // webpack core
var WebpackDevServer = require('webpack-dev-server'); // Server plug-in provided by webpack
var config = require('./webpack.dev.config.js'); // Web pack configuration file
/* Here's how to create a service object in fixed form */
var server = new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath, // The file relative reference path is configured in the configuration file.
hot: true, // Whether hot update is enabled
inline: true, // Whether to refresh in real time, that is, the code has changed, automatically refresh the browser
historyApiFallback: true, // All url paths jump to index.html and need to be set to true. Otherwise, if you visit localhost:8888, you won't be able to jump to the / home page.
progress: true, // Output webpack compilation progress in console
stats: { colors: true }, // Different types of information are displayed in different colors
});
/* Return all access paths to index.html */
server.app.get('*', function(req, res) {
res.sendFile(__dirname + '/src/index.html')
});
/* Startup service */
server.listen(8888, function() {
console.log('Startup service: port 8888')
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
The command to start the service is already configured in package.json:
Run npm run watch
Now start the service and nothing will happen, because src/app.js and src/index.html are empty
After that, configure. Let's take a look at the webpack configuration file needed to configure the final packaging.
8. Configure webpack.production.config.js
That is, the configuration required for the formal packaging that will ultimately be used in the production environment
webpack.production.config.js:
var path = require('path'); // To get the project root path
var webpack = require('webpack'); // webpack core
var ExtractTextPlugin = require('extract-text-webpack-plugin'); // To pack css separately
var HtmlWebpackPlugin = require('html-webpack-plugin'); //Generate the final html file based on the template
var ROOT_PATH = path.resolve(__dirname); // Project Root Path
var APP_PATH = path.resolve(ROOT_PATH, 'src'); // Project src directory
var APP_FILE = path.resolve(APP_PATH, 'app'); //Project entry file (src/app.js)
var BUILD_PATH = path.resolve(ROOT_PATH, 'build/dist'); //The directory where the packaged files are stored (usually named this way)
module.exports = {
entry: {
app: APP_FILE, // Files that need to be packaged, just this entry file
},
output: {
path: BUILD_PATH, // Pack files into this directory
publicPath: '/', // In the generated html, the file introduction path will be relative to this address, and the generated css, as well as the URL s of various pictures, will be relative to this address.
// Because all the packaged files are to be submitted to the background programmer, and then assembled into a complete project together with the background program. After online, there must be a website to visit, such as: www.test.com;
// So all the URL s in the front-end code are relative to this address, so we configure publicPath as'/'. For example, the path of the home page is www.test.com/home, and the access path of the picture test.jpg is www.test.com/images/test.jpg.
// The most important thing is routing jump. We will configure react routing later. For example, the publicPath is'/'. route access to the home page in the routing should be configurated as follows:
// <Route path="/home" component={homeContainer} />
// For example, publicPath is configured with'/ xxx', and route should be:
// <Route path="/xxx/home" component={homeContainer} />
// Usually it is configured as'/', because a project will have a top-level domain name pointing to it when it goes online, but when we test it ourselves, such as when you finally pack it and put the code into tomcat to run, tomcat access must be: http://localhost:8888/myreact, which is not a top-level domain name, you should configure publicPath as'/myreact', and also configure it accordingly in the routing. Ome
filename: '[name].js', // The resulting file name, app.js in the project, will eventually be called app.js.
chunkFilename: '[name].chunk.js', // This is the name of the final file generated by configuring some non-entry files, such as code segmentation, loading on demand, and packaging some files in your project separately, which will be used. We only have one app.js here, so this one won't work for the time being.
},
/* Various parsers */
module: {
loaders: [
// Parse. js,.jsx
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
},
// Parse. css. Note that this plug-in is used here as a loader before a separate CSS file can be generated.
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style', ['css']), // Written in this way, this type of file is packaged separately into a css file
},
// Analytical less, the principle is the same as above
{
test: /\.less$/,
loader: ExtractTextPlugin.extract('style', ['css','less']),
},
// Resolve all kinds of non-picture files
{
test: /\.(eot|woff|svg|ttf|woff2|gif|appcache|mp3)(\?|$)/,
exclude: /node_modules/,
loader: 'file-loader?name=[name].[ext]',
},
// Parse the picture, convert less than 8kb to base64
// Notice that the name in the mating is generated under the images folder
{
test: /\.(png|jpg|gif)$/,
exclude: /node_modules/,
loader: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]',
}
]
},
/* Additional plug-ins */
plugins: [
new webpack.DefinePlugin({ // Be sure to configure this. This is to tell webpack what mode to package code, production mode, dev development mode to use at present.
'process.env': {
NODE_ENV: JSON.stringify('production') //Define production environment
}
}),
// Detailed tutorial for this plug-in http://www.cnblogs.com/haogj/p/5160821.html
new HtmlWebpackPlugin({ //Generate the final HTML by inserting css/js etc. into the template
filename: '../index.html', //The generated html storage path, relative to (note that the BUILD_PATH configuration is "build/dist", that is, index.html will be generated under build, other files will be packaged under build/dist)
template: './src/index_template.html', //html template path
inject: true, // Whether to put js at the end of body
hash: false, // Whether to add a unique hash value to all resource files on this page
}),
// Configure this plug-in, and with the configuration in the loader above, package all style files into a single css file
new ExtractTextPlugin('[name].css'),
// Extract those common modules and code and package them into a separate js file
// The third parameter of this method is automatic matching. The webpack traverses all resources and finds that the module is a module, and the module is not in the src directory, it is extracted into the public js.
// That is, all the packages used in node_modules are packaged separately into a js, and if there is css, a vendors.css file will be generated separately.
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', (module, count) =>
module.resource && module.resource.indexOf(APP_PATH) === -1),
// Uglify Encrypted Compressed Source Code
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false, // Delete all comments in the code
},
compress: {
warnings: false, // Estimates don't output warning information, etc.
},
}),
],
// Configure additional solutions
resolve: {
extensions: ['', '.js', '.jsx', '.less', '.css'], //Automatic Completion of Suffix Names
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
9. Write index.html and index_template.html templates
index.html:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
<title>Project name</title>
</head>
<body>
<div id="app-root"></div>
<script src="/test/bundle.js"></script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
In the above code, because the output.publicPath configured in webpack.dev.config.js is'/ test/',
So the script tag in html corresponds to / test/bundle.js
The index.html above is just for development purposes, start the service, and then jump to the html.
index_template.html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
<title>entry name</title>
</head>
<body>
<div id="app-root"></div>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
This template html is used to generate the final index.html when it is really packaged, which can be used directly by backstage personnel. js and css, web pack is automatically added to the final index.html
So far, the basic prototype has been configured to work properly. In the next article, react,redux, and basic business logic will be added to the basic framework.