This article is aimed at the interview questions:

  • Have you built a VUE project manually?
  • Webpack basic configuration knowledge?

Recently, several colleagues in different positions around me have changed jobs, so I also come to review (learn) the knowledge related to project construction, so that I don’t feel so anxious.

Based on: vue2 & WebPack5

Go ahead, build it manually.

Initialize the project

Select a directory initialization project

mkdir dashboard
cd dashboard
npm init
Copy the code

Execute the above commands and initialize the project as prompted. A package.json file will be automatically created in the Dashboard directory. Something like this:

{" name ":" dashbord ", "version" : "1.0.0", "description" : ""," main ":" index. Js ", "scripts" : {" test ", "echo \" Error: no test specified\" && exit 1" }, "author": "lucky", "license": "ISC" }Copy the code

The introduction of webpack

npm install webpack webpack-cli -D
Copy the code

Running the preceding command automatically generates the node_module directory and package-lock.json file, and downloads webpack and webpack-CLI packages. The current directory structure looks like this:

> node_module
package-lock.json
package.json
Copy the code

Add the gitignore file

Add the. Gitignore file to the root directory and set the node_modules folder to unuploaded

node_modules/
Copy the code

Basic WebPack configuration

Create a new webapck directory under the root directory and create the webpack.config.js file

touch webpack.config.js
Copy the code

The core idea of Webpack is packaging, packaging all files other than JS into files that JS can use. Configure webPack entries, exits, plug-ins, and modules

const path = require("path");
module.exports = {
  mode: "development".// Use the appropriate built-in optimizations for your environment
  entry: "/src/index.js".// Import file
  output: {
    // Export file
    filename: "bundle.js".path: path.resolve(__dirname, ".. /dist"),
    publicPath: "/",},plugins: [].// The plug-in to use
  module: {
    generator: {}, / / generator
    parser: {}, / / the parser
    rules: [].// Change how the module is created
  }, // Module loading scheme
};
Copy the code

Don’t forget to execute NPM I path

Test webPack packaging

Now let’s create a new index.js file

const a = { x: 1 };
console.log("Test pack!", a);
Copy the code

Then execute Webpack on the command line

webapck ./index.js
Copy the code

As you can see, a dist directory is generated in the root directory, and the export file bundle.js is generated in the dist directory:

console.log("Test pack!", { x: 1 });
Copy the code

Now that webPack has been introduced and can be packaged properly, the next step is to package configuration files into HTML.

The test packages the code into an HTML file

Start by generating an HTML file in the root directory

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Document</title>
  </head>
  <body></body>
</html>
Copy the code

To package JS, CSS and other codes into HTML files, we need htmlWebpackPlugin. The html-webpack-plugin creates an HTML file and inserts the webpack-packed static file into the HTML file when using webpack. Run the following command from the command line to install the plug-in:

npm install html-webpack-plugin --save-dev

Copy the code

Introduce the above plug-ins in the webpack.config.js file:

const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html".filename: "index.html".title: "Vue -> Web App".minify: {
        collapseWhitespace: true.// Remove whitespace
        removeComments: true.// Remove the comment}}),]};Copy the code

Execute the webpack command from the command line:

webpack ./index.js --config ./webpack/webpack.config.js
Copy the code

Now the dist directory is automatically generated in the root directory:

dist
 budle.js
 index.html
Copy the code

Bundle. Js:

/* * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to  create a separate source file in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */
/ * * * * * * / (() = > {
  // webpackBootstrap
  / * * * * * * / var __webpack_modules__ = {
    / * * * / "./index.js":
      / *! * * * * * * * * * * * * * * * * * *! * \! *** ./index.js ***! \ * * * * * * * * * * * * * * * * * * /
      / * * * / () = > {
        eval(
          "const a = {x: 1}; \nconsole.log(' Test package! ', a); \n\n\n//# sourceURL=webpack:///./index.js?"
        );

        / * * * /
      },

    / * * * * * * /
  };
  / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
  / * * * * * * /
  / * * * * * * / // startup
  / * * * * * * / // Load entry module and return exports
  / * * * * * * / // This entry module can't be inlined because the eval devtool is used.
  / * * * * * * / var __webpack_exports__ = {};
  / * * * * * * / __webpack_modules__["./index.js"] ();/ * * * * * * /
  / * * * * * * /}) ();Copy the code

Index.html:

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Document</title>
    <! -- Notice here -->
    <script defer="defer" src="/bundle.js"></script>
  </head>

  <body></body>
</html>
Copy the code

Looking at the code above, a script was automatically inserted into the HTML that imported our index.js wrapped code.

So far we have completed a webpack shelf, but we still use vue, React and other front-end frameworks and UI frameworks for daily development, which we will introduce later.

Configure the NPM run build

Json (package.json) :

"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack ./src/index.js --config ./.. /webpack/webpack.config.js" },Copy the code

When using NPM run build directly can be packaged.

The introduction of vue

  • Vue can be introduced in script. Here we use NPM to introduce vue:
npm i vue
Copy the code

Vue is a front-end framework, its two core ideas are: two-way data binding, componentization. Create a new app. vue file in the SRC directory

<template> <div> This is a vue file </div> </template>Copy the code

Modifying HTML files

<body>
  <div id="app"></div>
</body>
Copy the code

Modified index. Js:

import Vue from "vue";
import App from "./App.vue";
new Vue({
  el: "#app".render: (h) = > h(App),
});
Copy the code

NPM run build is definitely not going to work because WebPack doesn’t recognize vue files yet. Vue-loader must be installed first:

npm i vue-loader --save-dev
npm i cache-loader --save-dev
npm i thread-loader --save-dev
Copy the code

Cache-loader is used to add the cache-loader before some loaders that require high performance to cache the results to disks.

Thread-loader provides the following functions:

If you place this loader before other loaders, loaders placed after this loader will run in a separate worker pool

Modify the webpack. Config. Js:

const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
  plugins: [new VueLoaderPlugin()],
  module: {
    rules: [{test: /\.vue$/,
        use: [
          {
            loader: "cache-loader"}, {loader: "thread-loader"}, {loader: "vue-loader".options: {
              compilerOptions: {
                preserveWhitespace: false,},},},],exclude: /node_modules/,},],},};Copy the code

Install vue-template-compiler and HTMl-loader

npm i vue-template-compiler --save-dev
npm i html-loader --save-dev
Copy the code

Now run the NPM run build package and run it with the Node.js static service. You can see the words “this is a Vue file” in our Vue component.

Configuration devServer

Using NodeJS to run static files is cumbersome. Now we configure webpack devServer, which comes with Webapck

npm install webpack-dev-server -D

Copy the code

Enable devServer in webpack.config.js:

module.exports = {
  devServer: {
    port: 3005.// Start port
    hot: true.// Whether to enable hot module replacement
    open: true.// Whether to enable automatic page opening
    proxy: {
      // Proxy rule
      "/api": {
        target: "http://123.123.123.123:8080".secure: false.changeOrigin: true.pathRewrite: {
          // Redirection rules
          "^/api": "/api",},},},},};Copy the code

Add the command dev to the shell:

    "dev": "webpack-dev-server --config ./webpack/webpack.config.js",
Copy the code

Start the NPM run dev project at http://localhost:3005. Note If the port is occupied, start with another port. At this point we have a basic framework for webPack to manually configure the VUE project. Let’s start development. Here I chose vUE’s good friend, Element-UI, to develop.

Introducing the element – the UI

Execute from the command line:

npm i element-ui -D
Copy the code

Modified index. Js:

import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";

Vue.use(ElementUI);
Copy the code

Here we have introduced the element-UI CSS file, so we need to add csS-loader first:

npm i style-loader css-loader -D
Copy the code
module.exports = {
  module: {
    rules: [{test: /\.css$/,
        use: ["style-loader"."css-loader"],},],},};Copy the code

Add an el-button to app. vue to test it:

<el-button type="primary">Hello element - the UI</el-button>
Copy the code

Now that we restart the service, we can see that the blue button (the default element- UI color) is displayed on the page. Happy ~!

Support SCSS

npm i css-loader style-loader sass sass-loader -D
Copy the code

Rules added in the webpack.config.js file,

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

Modify the UI theme color

Element’s theme-chalk is written using SCSS. If your project uses SCSS, you can change Element’s style variables directly in your project. Create a new style file, such as element-variable.scss

/* Change the theme color variable */$-color-primary: teal;

/* Change icon font path variable, required */$-font-path: "~element-ui/lib/theme-chalk/fonts";

@import "~element-ui/packages/theme-chalk/src/index";
Copy the code

Modified index. Js

// import "element-ui/lib/theme-chalk/index.css";
import "./element-variables.scss";
Copy the code

Once done, the blue background of the buttons on the interface changes to green tea color. Then we can use element-UI to start developing the CRM system interface.

ES6 syntax is supported

Add the test code to app.vue:

<script> export default { async created(){ const timeout = function(time){ return new Promise(resolve => { setTimeout(resolve, time); })}; console.log('11111'); await timeout(3000); console.log('22222'); }, } </script>Copy the code

After saving, we found an error, because our Webpack does not support ES6. Modify webpack.config.js and add rules

      {
        test: /\.js$/,
        use: {
            loader: 'babel-loader'.options: {
                cacheDirectory: true.presets: ['@babel/preset-env'].plugins: [
                    '@babel/plugin-transform-runtime'.'@babel/plugin-transform-modules-commonjs',]}},exclude: /node_modules/,},Copy the code

Configure nginx

This project deploys the nginx proxy I used:

access_log /dev/stdout;

server {

  listen 80 default_server;

  location / {
    root /app/dist;
    try_files $uri $uri/ /index.html;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ( !-f $request_filename ) {
      rewrite ^/(.*) /index.html break;
    }
    if ($request_method = 'OPTIONS') {
      return 204;
    }
  }

  location /service-name/ {
    proxy_pass http://service-name:8080/;
    index index.html index.htm;
  }
}
Copy the code

According to nginx’s documentation, configuring a forward proxy for a service is fine, and configuring a reverse proxy is simple. However, I ran into a problem with differentiating between different environments: different environments access different back-end service addresses that need to be dynamically configured. Here I use the method of directly configuring the service name in the Ranchers cluster.

Enable Gzip compression

Gzip can be added to HTTP or server segments.

http {
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/javascript application/json;
    gzip_disable "MSIE [1-6]\.";
    gzip_vary on;
}

Copy the code

conclusion

This article covers webpack configuration, identifying Vue files, configuring devServer, Element-UI, Nginx deployment, and GZIP configuration. The basic framework is already available, and you can install plug-ins and loaders when you encounter them during development.

This is the end of the article, the above steps have been posted on Github, if you want to see a CRM system development framework to build follow-up content, you can leave a message in the comments section.

tips

Previously, all new VUE projects were cli tools, so I don’t know much about the construction process. At the beginning of this year, I was always afraid to build my own projects with WebPack, but now I am not afraid at all as I have been building and deploying new projects in the last 2 months. Although there are a lot of knowledge, but, as long as believe in yourself, and brave to take the first step, there is no problem can not be solved, everyone refueling! Criticism is welcome, meow!