Set up the React Project

Initialize the NPM environment

NPM init Selects configuration items to obtain package.json file

Install webpack

npm i webpack webpack-cli -D

Create directories and configuration files

Create webpack.config.js and write the configuration file.

const path = require('path') / / introduce 'path'
module.exports = {
    // Application entry
    entry: {
        app: path.join(__dirname, './src/index.js') // index.js as the entry point for packing
    },
    // Output directory
    output: {
        filename: 'build.js'.// filename: '[name].[hash:8].js', //name indicates the name corresponding to the entry; Hash means that the whole app is packaged and hash is added according to the content. As soon as the entire file content changes, the hash changes
        path: path.join(__dirname, 'dist'), // The packaged output path}}Copy the code

Modify the package. The json

"build": "webpack --mode production"
Copy the code

Babel-loader needs to be introduced

NPM I babel-core [email protected] babel-env -d

npm install babel babel-cli -D

npm install babel-preset-react babel-preset-es2015 -D

npm install babel-preset-stage-0 -D

Configure loder in webpack.config.js

. module: {rules: [{
      test: /\.(js|jsx)$/.// Use the loader target file. Here is js
      use: {
        loader: 'babel-loader'
      },
      exclude: [
        path.join(__dirname, '.. /node_modules') // Since node_modules are compiled files, we don't let Babel handle the js files underneath it]]}}Copy the code

Create a configuration file for Babel in the project root directory:.babelrc

{
    "presets": [
        "react"."es2015"."stage-0"]."plugins": [
        "transform-decorators-legacy"]}Copy the code

Install the CSS – loader

npm i css-loader style-loader -D

Modify the configuration file and add plugins

. module: { rules: [{test:/\.css$/,
            use: ['style-loader'.'css-loader']}...Copy the code

Install the url – loader

npm i url-loader -D

Modify the configuration file and add plugins

. module: { rules: [ .... {test:/\.(jpg|png|jpeg|gif)$/,
            use: {
                loader:"url-loader"}}...Copy the code

Using HTML Templates

npm i html-webpack-plugin -D

Modify the configuration file and add plugins

const HTMLPlugin = require('html-webpack-plugin')... . plugins: [new HTMLPlugin({
      filename: 'index.html'.// Make the file by default
      template: 'index.html' // Specify the template file to use for HTML generation
    }) // Generate an HTML page while WebPack is compiling. Inject all the entries we generated into the HTML page, and the path is based on our output configuration.
  ]
Copy the code

Creating an HTML template

Create an index.html file in the following directory

<! DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <title>demo</title> </head> <body> <div id="root"></div> </body> </html>Copy the code

Development mode hot update

npm i webpack-dev-server -D

Add to script in package.json

"dev": "webpack-dev-server --mode development --open".Copy the code

Execute NPM run dev and the project is ready to run

Install the react

npm i react react-dom -S

Create the SRC folder and create the index.jsx entry file in the SRC folder

import React from 'react'
import ReactDom from 'react-dom'

class Demo extends  React.Component{
  render() {
    return (
      <div>hello word</div>
    )
  }
}
export default Demo

ReactDom.render(<Dome />, document.getElementById('root'))
Copy the code

Set up the React Project

Install mobx-router-dom mobx mobx-react antd

npm i react-router-dom mobx mobx-react antd -S

To build the skeleton

Mobx configuration

index.js

import news from "./list"/// Default export interfaceexport default {
    news
}
Copy the code

list.js

import { observable, action } from 'mobx'

class News {
    @observable list = [
        {
            id: 1,
            title: 'Giannis Antetokounmpo 33+16 bucks beat Pistons 50+8 Hawks beat Heat',
            content: The second half of the NBA is on fire after the All-Star break on Feb 21, Beijing time. Milwaukee's road win over Detroit; The Heat lost on the road to Atlanta, failing to complete a sweep. Here's a roundup of the two matches. ',
        },
        {
            id: 2,
            title: 'Us experts predict antetokounmpo's reigning MVP title belongs to LA',
            content: As the regular season enters its second half on February 20 (Beijing time), sports media asked a panel of experts to make their predictions for the big prizes and playoff results. ',
        }
    ]
    @action setList(val) {
        this.list = val
    }
}

export default new News()
Copy the code

The routing configuration


import React from 'react'
import Add from '.. /pages/add/index.jsx'
import List from '.. /pages/list/index.jsx'
import Detail from '.. /pages/detail/index.jsx'
import Nwjs from '.. /pages/nwjs/index.jsx'
import { Route } from "react-router-dom"
 
const routes = [
    {
        path: "/add",
        component: Add
    },
    {
        path: "/list",
        component: List
    },
    {
        path: "/detail/:id",
        component: Detail
    },
    {
        path: "/nwjs",
        component: Nwjs
    }
]

function RouteWithSubRoutes(route) {
    return( <Route path={route.path} render={props => ( <route.component {... props} routes={route.routes} /> )} /> ) }export { routes, RouteWithSubRoutes }

Copy the code

NW. Try js

Nw package.json configuration is as follows

{
    "name": "helloworld"."main": "http://localhost:8000/"."node-remote": "http://localhost:8000/"."window": {
        "width": 1000,
        "height": 600,
        "position": "center"."min_width": 400,
        "min_height": 200}}Copy the code

SRC /pages/ NWJS /index.jsx code is as follows

import React, { Component } from 'react'
import { Button, Divider, message } from 'antd'
import icon from '.. /.. /images/vip.png'
import './index.css'

class Nwjs extends Component{
    constructor(props) {
        super(props)
        this.state = {
            win: null
        }
    }

    componentDidMount() {enclosing setState ({win: nw. Window.} get () / / retrieve the current Window, () = > {/ / release when the new Window'win'Check object this. State. Win.'closed'.function() {
                this.setState({
                    win: null
                })
            })
        })
    }

    render() {
        return (
            <div>
                <Button type="primary"OnClick ={this.minimize}> minimize the window </Button> <Button className="mg-left" type="primary"OnClick ={this.maximize}> </Button> <Button className="mg-left" type="primary"OnClick ={this.normal}> Default window </Button> <Button className="mg-left" type="primary"OnClick ={this.close}> Close the window </ Divider > <Buttontype="primary"OnClick ={this.createMenu}> Create a menu </Button> <Divider /> <Buttontype="primary" onClick={this.shell}>shell</Button>
                <Divider />
                <Button type="primary"// Window minimize minimize = () => {const {win} = this.state // listen for minimize events win.on() {// window minimize = () => {const {win} = this.state'minimize'.function() {
            console.log('Window minimization')}); // Window minimizes win.removealllisteners () // can minimize win.removealllisteners ('minimize'Maximize = () => {const {win} = this.state win.maximize()} // Default window normal = () => {const {win} = this.state win.resizeTo(1000, Close = () => {const {win} = this.state win.close()} createMenu = () => {// Create an empty menubar var menu = new nw.Menu({type: 'menubar'}) var submenu = new nw.menu () submenu.append(new nw.menuitem ({label:'Menu item A', 
            icon: icon,
            tooltip: 'test',
            click: function() {
                console.log("You have selected menu item A");
            }
        }))
        submenu.append(new nw.MenuItem({ type: 'separator' }))
        submenu.append(new nw.MenuItem({ 
            label: 'Menu item B'.type: 'checkbox',
            checked: true})) // Create and append the first level menu to menu.append(new nw.menuitem ({label:'First menu', submenu: Submenu})) // Pop window as context menu menu.popup(10, 10) // assign to 'window.menu' and display menu nw.window.get ().menu = menu message.success('Created successfully')
    }

    // shell
    shell = () => {
        nw.Shell.openExternal('https://github.com/nwjs/nw.js'// Open the specified.nw.shell.openitem file in the default editor.'.. /.. /.. /README.md'} // Create tray = () => {// create tray icon var tray = new nw. tray ({title:'Tray'Var menu = new nw.menu () menu.append(new nw.menuitem ({var menu = new nw.menu () menu.append(new nw.menuitem ({type: 'checkbox', label: 'box'})) tray.menu = menu; Tray. remove() tray = null}}export default Nwjs
Copy the code

conclusion

The main purpose of this task is to familiarize yourself with react and its related ecosystem, and combine it with a simple demo of nw.js implementation. The complete code can be found here