1 react basic documents:
React from Import 'REACT' ; Import ReactDOM from 'DOM-REACT' ; Import from the App './App.jsx' ; ReactDOM.render ( <the App />, document.getElementById ( 'the root')) // the assembly app reactCreateElement passed as a parameter to be introduced react
basic configuration:
the require path = const ( 'path' ); module.exports = { entry: [ App: path.join (__ dirname, '../clinet/app.js'); // Use path, an absolute path is provided, in front of attention dirname two underscores ], Output: [ filename: '[name]. [the hash] .js', // time-dependent changes of the document, hash value change. path: path.join (__ dirname, '.. / dist'), // output absolute path publicPath: '/ public' // set file referenced public path, a path for setting CDN ], Module1: { the rules: [ { Test: /.jsx$/ , Loader: 'Babel-Loader'// compile jsx, es6, es7 and other syntax // here to install babel: npm i babel-Loader -D // babel-Loader is just a webpack plug, not including the babel of the core code, so also install: // babel -core: I bable NPM -D-Core // further, bable-core default build es6, in order to further compile JSX, so to be further configuration: .babelrc file } ] } }
// .babelrc file { "Presets": [ // Specify what types compiled babel [ "ES2015", { "Loose": to true }], // specified ES2015 is not critical loose "REACT" // here adding on react, after the support, babel will react to compile the code ] } // attaching the dependencies: // NPM-I Babel Babel-PRESET PRESET-ES2015 ES2015-Loose-PRESET-react -D-Babel
To open the html file:
Installation: . 1 NPM-I HTML WebPACK -D-plugin
the require path = const ( 'path' ); const HTMLPlugin = the require ( 'HTML-WebPACK-plugin' ) module.exports = { entry: [ App: path.join (__ dirname, '../clinet/app.js') ; // use path, an absolute path is provided, in front of two underscores noted dirname ], Output: [ filename: '[name] [the hash] .js.', // time-dependent changes of the document, hash value change. path: path.join (__ dirname, '.. / dist'), // output absolute path publicPath: '/ public' // set file referenced public path, a path for setting CDN ], Module1: { the rules: [ { Test:/.jsx$/ , Loader: 'Babel-Loader' // compile jsx, es6, es7 like syntax // here to install Babel: Babel NPM-I Loader -D @ Babel-Loader webpack just a plug, not including babel core code, so also install: // babel-core: core -D-NPM bable I // further, bable-core default build es6, in order to further compile JSX, so to be further configuration: .babelrc file }, { Test: /.js$/ , Loader: 'Babel-Loader' , the exclude: [ path.join (__ dirname, '../node_modules' ) ] } ] }, plugins: [ new new HTMLPlugin (); // has two functions: to generate a html document, 2: the configuration package according to the output file entry ] }
2 side rendering service configuration
Single-page problems:
1 SEO unfriendly
2 first request you wait too long, unfriendly experience.
Page code:
// the file on the server running Import from React 'REACT' ; Import from the App './App.jsx' ; Export default <the App />
Create a new server-side webpack packaged file:
the require path = const ( 'path' ); module.exports = { target: 'Node', // this is a new configuration, web / node using a predetermined Where entry: [ App: path.join (__ dirname, '.. /clinet/serve-entry.js' ); ], Output: [ filename: 'server-entry.js', // Node.js to improt this js file is not cached at the server and does not require the hash path: path .join (__ dirname, '.. / dist'), // absolute path output publicPath: '' , libraryTarget: 'commonjs2' // packed out program module js used, including AMD CMD CommonJS other specifications, use herein is commonjs2, applicable to the end node ], module:{ rules:[ { Test: /.jsx$/ , Loader: 'Babel-Loader' // compile jsx, es6, es7 like syntax // here to install Babel: Babel NPM-I Loader -D @ Babel a just-Loader webpack plug-in, not including the babel of the core code, so also install: // babel-core: npm i bable -D-core // in addition, bable-core default is to compile es6, in order to also compile jsx, so to be further configuration: .babelrc file }, { Test: /.js$/ , Loader: 'Babel-Loader' , the exclude: [ path.join (__ dirname, '../node_modules' ) ] } ] } }
Modify configuration items:
// modify package.json file { "Script" : { "Build: Clinet": "WebPACK --config Build / webpack.config.client.js" , "Build: Server": "WebPACK --config Build / WebPACK. config.server.js " , " the Clear ":" rimraf dist " // rimraf is a node of a package, designed to delete the folder " build ":" npm run clear && npm run build: client && npm run build: server " , } }
// rimraf installation package. npm i rimraf -D
Then each finished package, js file there will be three clients and a server-side js html.
Write the following express service side: first install npm i express -S
New server folder creation server.js file:
Description: 1: dist / server-entry file is generated packaged js file; res.send () is generated rendering js file;
2.app.get get to all the requests the browser, return rendered js files; listening port in 3333
2: Since the html syntax is used to es6: Export default <the App /> ; and the node can not use the impront {app} from './app' This syntax structure assignment, so here use require (). default get the default value;
Json then in the configuration file, set the server startup command:
{ "script":{ "start": "node server/server.js " } }
After running server-side code, the server returns the file only after entry package to write code string: '<div> </ div>', we need to return the entire html.
Step one: Create a new template file folder first template.html in the client file: where the key code:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="root"><app></app></div> </body> </html>
Generating overwrite the file <app> </ app>;
Then modify the client configuration file. webpack.config.client.js templates plug-ins:
{ plugins: [ new HTMLPlugin({ template: path.join(__dirname, '../client/template.html') }) ] }
Note that this is a change of the client's configuration file, the client package generated html files, then references to the server:
Express the require = const ( 'Express' ) const ReactSSR = the require (' DOM-REACT / Server ' ); const FS = the require (' FS ' ) const path = the require (' path ' ) const serverEntry = the require (' ../ dist / Server-entry '). default ; // introduced after the configuration package js file server const template = fs.readFileSync (path.join (__ dirname,' ../dist/index.html '),' utf8 ') // synchronization pull html file generated by the client package, if it is not used utf8 buffer file const App = Express (); app.use ( ' / public ', express.static (path.join (__ dirname,'. ./dist ' )));// specify a return to the static file content, content here to return under piblic folder dist file is a static file folder app.get ('*', Function (REQ, RES) { const appString = ReactSSR.renderToString (serverEntry); res.send (template.replace ( '<App> </ App>', appString)) // replaced with the returned file js out template <app>, the template file is then transmitted }) app.listen ( 3333, function () { the console.log ( 'Listening Server iS ON 3333' ) })
Note that: output configure the client and server in publicPath write for the "public"
Output: [ filename: '[name] [the hash] .js.', // time-dependent changes of the document, hash value change. path: path.join (__ dirname, '.. / dist'), // output absolute path publicPath: '/ public' // set file referenced public path, the path for setting CDN ]
Html Such generated static document referenced js and css path and prefix are pictures in public, so the server server.js above app.use ( '/ public', express.static (path.join (__ dirname , '../dist')));
Returns the file to the dist directory access files in the public folder in the file, template file other returns *
- Question 1 Why would also like to set up public on the server's configuration file
- app.js server-entry.js and client service side of Question 2 so what's the difference?
app.js client can operate on the browser, such as
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(<App/>,document.getElementById('root'))
And the server may not:
import React from 'react'; import App from './App.jsx'; exprot defalut <App/>
Therefore subsequent corresponding webpack.config configuration files need to provide two, corresponding to the client and server side;
two of them are not the same inlet and outlet configuration
client configuration file:
{ Entry: [ App: path.join (__ dirname, '../clinet/app.js'); // Use path, an absolute path is provided, in front of two underscores noted dirname ], Output: [ filename: ' [name ]. [the hash] .js', // time-dependent changes of the document, hash value change. path: path.join (__ dirname, '.. / dist'), // absolute path output publicPath: '/ public' // set file referenced public path, a path is provided for the CDN ], }
Server configuration file:
{ Target: 'Node', // this is a new configuration, web / node using a predetermined Where entry: [ App: path.join (__ dirname, '../clinet/serve-entry.js' ); ], Output : [ filename: 'server-entry.js', // Node.js to improt this js file is not cached at the server and does not require the hash path: path.join (__ dirname, '.. / dist'), / / absolute path output publicPath: '' , libraryTarget: 'commonjs2' // packed out program module js used, including AMD CMD CommonJS other specifications herein are commonjs2, applicable to the end node ], }
Thus, the server is a separate entrance js file and the output file.
According to the template file generation:
<body> <div id="root"><!-- app --></div> <script type="text/javascript" src="/public/app.9337b7bd3bfeb9af5f86.js"></script> </body>
Wherein the client package, the client js script file stored in the tag, the server file server-entry.js placed server.js server id == 'root' div with, the two will be added / public, so that the server returns the corresponding js files instead of template code.