The complete code has been uploaded to Github, click to visit

The preparatory work

1. Select appropriate pre-processing tools and resource management tools for the front-end

Preprocessing tools are divided into JS preprocessing tools and CSS preprocessing tools. Javascript has long been criticized for its lack of a native module mechanism, where all JS code files share the same namespace after being introduced into HTML pages. As a result, various “standards” have emerged to try to solve this problem, but they are not native and require additional tools to make the code special. While ES6 has finally introduced a module mechanism, the current level of browser support is not enough to “just grab it and use it”. So the main job of JS preprocessing tool is to help solve the js module problem. CSS preprocessing tools, on the other hand, are easy to understand, translating and combining Sass, less, or stylus code into CSS code.

Resource management tools help us manage the various resource files (such as CSS, JS, images, fonts, etc.) needed by the front end, so that we can reference them easily. The current workaround is to code them directly into JS code and then reference them as if they were JS modules. It’s much easier than writing urls by hand.

As the title says, we’ll go with Webpack because it has all the features mentioned above. It also supports code hot replacement, making code changes immediately visible in the browser without having to refresh the page.

2. Select an appropriate preprocessing tool for the backend

The backend is all JS code and doesn’t require the same resource management tools as the front-end, plus Node forces you to use at least one module management solution (CommonJS or ES6 import) and doesn’t have to worry about code dependencies.

So the back end is much simpler, and the only thing left to think about is basically how to translate ES6 to ES5 (if you’re going to use ES6). The most common approach is to use Babel. You can use the Babel command line tool to perform compilation independently, or you can configure the Babel Register to translate code dynamically at run time, which is most convenient for development scenarios. So we choose the latter way.

3. Select appropriate process control tools for the entire project

Flow control tools are designed to help us manage tasks such as code review, compilation, compression, movement, and deployment, which we used to do by typing commands (or writing a script at a more advanced level) with configuration files and a little code.

The most popular solution is GULP. However, since we are building a development environment with no requirements for moving code, compression, deployment, etc., there is no need for powerful Gulp. All we have to do is use the Nodemon tool to listen for code changes and then restart the server when appropriate.

Officially start construction

1. Use Express scaffolding to build applications quickly

Using the Express Application Generator, you can build a basic application in less than 1s.

If you haven’t tried it before, execute the following command to install it first

npm install express-generator -g

Then run the following command to generate the code, which requires some parameters to be entered.

express <myapp>

The finished file structure looks like this

. ├ ─ ─ app. Js ├ ─ ─ bin │ └ ─ ─ WWW ├ ─ ─ package. The json ├ ─ ─ public │ ├ ─ ─ images │ ├ ─ ─ javascripts │ └ ─ ─ stylesheets │ └ ─ ─ Style. CSS ├── routes │ ├─ index.js │ ├─ download.js │ ├─ download.htm │ ├─ download.htm │ ├─ download.htm │ ├─ download.htm │ ├─ download.htm │ ├─ download.htm │Copy the code

But this file structure is just back-end code, and some changes are needed to combine it with the front-end code. Our final document structure should look like this

. ├ ─ ─ the SRC │ ├ ─ ─ client │ └ ─ ─ server └ ─ ─...Copy the code

So you need to put the Express code generated automatically above in the/SRC /server/ path.

Next we need to remove some unnecessary things and add some missing things.

First, since we intend to use the Vue framework on the front end, with vue-Router managing most of the routes, and Express on the back end retains only a small number of RESTful API routes, there is no need for complex routing Settings on the back end. The content in the Routes folder can be simplified to a phones. js file.

Next, we need to configure the Babel register, so we need to add two files. Babelrc and index.js under the project and path, respectively:

/.babelrc

{
  "presets": ["es2015"],
}
Copy the code

.babelrc is a required file for Babel 6.0

/.index.js

require('babel-register')
require('./src/server')
Copy the code

Bebel registers all modules that require or import depend on and translates them into ES5.

There is a WWW file in the auto-generated code, which is the entry file for the Express application. We put it in the server path and renamed it index.js so that the Babel Register configured above can find it correctly.

Why was it renamed index.js? This is because require(‘./ SRC /server’) will look for./ SRC /server/index.js by default, if you want to use a different name, Change Babel Register configuration file to require(./ SRC /

.

All right, let’s stop at the back end and look at the front end.

2. Use Vue scaffolding to build applications quickly

Similarly, it is recommended to use the template tool that comes with Vue to generate basic code within 1s.

Although the back end of the code generated with this tool is express-based, the back end part of the code structure is too simple for further development. So it is recommended to put the vUe-generated code in a different place here, and then move it as needed to the previous Express generated code folder.

Start by installing the Template tool

npm install -g vue-cli

Then execute the command to generate the code. Some parameters are required during the command execution

vue init webpack <my-project>

The generated code structure looks like this

.├ ── Build │ ├─ Dev-server.js # Development Server script │ ├─ Karmap.conf # Unit Testing config │ ├─ ├── WebPack.dev.conf. Js # Shared Base webpack config │ ├─ webpack.dev.conf # Shared Base Webpack config │ ├─ Prod.conf. Js # production webpack config │ ├ ─... ├ ─ ─ the SRC │ ├ ─ ─ the main, js # app entry file │ ├ ─ ─ app. Vue # main app component │ ├ ─ ─ components # UI components │ │ └ ─ ─... │ ├ ─ garbage # module assets (exercises by webpack) │ ├ ─ ├ ─ ├── Exercise # ├── exercise # ├── exercise # ├── exercise # ├── exercise # Tests │ ├ ─ ─ index. Js # unit test entry file │ └ ─ ─... ├ ─ ─. Babelrc # Babel config ├ ─ ─ the eslintrc. Js # eslint config ├ ─ ─ index. The HTML # main HTML file └ ─ ─ package. The json # build scripts and dependenciesCopy the code

We found that there is also a.babelrc that is basically the same as the one we created before, so we can ignore it. In addition, it provides.eslintrc.js in conjunction with ESLint to check code for compliance. Here the content is very simple, want to be lazy to directly take over, feel customized rules do not conform to their own habits can be configured.

Webpack.base.conf.js and webpack.dev.conf.js are available in the build directory. It is recommended to merge the content into a webpack.conf.js file in the root directory of the project.

After that, I basically moved the SRC directory to the/SRC /client/ directory I created with Express. I used to change all js entry files to index.js so, Here you can also rename SRC /client/main.js to SRC /client/index.js.

The other files are ignored for now.

Here, the front-end part of the code is basically finished.

3. The configuration Webpack

We plan to let Webpack front-end files packaged into a build js file, and then put in/SRC/server/public/javascripts for jade template. So set up the path part of the Webpack (just leave everything else as it is) :

{... entry: path.join(__dirname, 'src/client/index.js'), output: { path: path.join(__dirname, 'src/server/public/javascripts/'), publicPath: '/javascripts/', filename: 'build.js' }, ... }Copy the code

As for how to start Webpack, you can choose to run it in a separate shell window, or you can provide proxies as Express middleware. In the latter way, WebPack does not generate the packaged code on disk, but keeps it in memory. We choose the latter method because it is more convenient.

Webpack should only be deployed in the development environment as Express middleware

/ SRC /server/index.js/SRC /server/index.js

import webpack from 'webpack' import webpackDevMiddleware from 'webpack-dev-middleware' import webpackHotMiddleware from  'webpack-hot-middleware' import config from '.. /.. /webpack.config' const compiler = webpack(config) app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, stats: { colors: true }, })) app.use(webpackHotMiddleware(compiler))Copy the code

In this way, each time Express is started, the Webpack middleware intercepts the request for the config.output. PublicPath address and returns the correct result, and if the file that Webpack listens for changes, it immediately notifies the front end of the change.

4. Configuration Nodemon

As mentioned earlier, the plan is to start the Server with Nodemon and listen for code changes. By default, Nodemon will listen to all JS codes except.git and node_modules paths. Since we already have Webpack listening to front-end codes, we have to configure Nodemon to only listen to a certain piece of code.

Add the nodemon.json file in the root path of the project

{
  "verbose": true,
  "ignore": ["src/server/public/"],
  "events": {
    "restart": "osascript -e 'display notification \"App restarted due to:\n'$FILENAME'\" with title \"nodemon\"'"
  },
  "watch": ["src/server/"],
  "env": {
    "NODE_ENV": "development"
  },
  "ext": "js jade"
}
Copy the code

Setting verbose to true prints richer log information, which is useful for development.

We chose to have Nodemon listen to the SRC /server/ directory and ignore the SRC /server/public directory because that’s where the front-end WebPack generates the package files. Note that we are using Webpack as Express middleware and do not actually produce files on disk, so this ignore rule can be omitted.

Don’t forget to add the JADE type to the file extension because Express uses the JADE template.

5. The configuration package. Json

Start by adding a command to script that launches the entire application

{... "scripts": { "dev": "nodemon index.js" }, ... }Copy the code

Thus, you only need to run the NPM run dev command to start the server while developing.