1
头图

background

In the past six months, several FreeMarker projects (hereinafter referred to as FM projects) have IE in the 0611cccad87060 browser or 360 browser compatible mode environment due to the use of ES6+ advanced syntax features to run errors online, resulting in business processes cannot be executed. Although it has been emphasized that development students should not use ES6 FM project, the verbal team convention is not very restrictive ES6 , which makes problems emerge in endlessly. In addition, there are also some Web Apis and 0611cccad87066 and There are compatibility issues with styles on IE Element.scrollIntoView() , Element.scrollTo() ). The API and styles also needs to be forcibly disabled, so tools are urgently needed to constrain during the programming phase.

The use ES6 or in poor compatibility Web Apis defects caused:

image-20210812142554665.png

Online problems caused by the use of ES6 or the poorly compatible Web Apis (all third-level events):

image-20210812143136040.png

In addition, because the jira not clear enough, the problems caused by style compatibility are not counted.

Program

The following program is only for ES6+ syntax compatibility characteristics and poor Web Apis process, otherwise for compatibility processing style programs.

Babel translation

In webpack (you can also use other build tools, such as gulp ) introduced babel will ES6 grammar translated into ES5 , but the source file needs to be done before building renovation as follows:

var managePage = {};

function  debounc() {}

After transformation:

window.managePage = {}

window.debounc =  function  debounc() {} 

Why not set libraryTarget: 'window' to a global variable output?

Because libraryTarget: 'window' packaging method can only be export exported objects to the way the global object output, the source code will need to do the following transformation after transformation, running on line no problem, the project will start in the local newspaper “xxx is not defined” , because export after parcel The variable becomes a local variable.

export var managePage = {};

export function  debounc() {}

babel-polyfill

babel only converts the js syntax by default, and does not convert the new API , such Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise , and some methods defined on global objects (such as Object.assign ) will not be transcoded.

For example, es2015 adds the Array.from method to the Array babel will not transcode this method. If you want this method to work, you must use babel-polyfill . (Integrated core-js and regenerator internally)

require('babel-polyfill') before all codes are run. Or more conventional operations are webpack.config.js will babel-polyfill as the first entry . babel-polyfill must be regarded as dependencies instead of devDependencies

babel-polyfill has two main disadvantages:

  1. Using babel-polyfill will result in a very large package, because babel-polyfill is a whole, and all methods are added to the prototype chain. For example, we only use Array.from , but it Object.defineProperty , which is a waste. This problem can be solved by using a certain class library of core-js core-js are all separate.
  2. babel-polyfill will pollute global variables and modify the prototype chain of many classes. If we develop a class library for other developers to use, this situation will become very uncontrollable.

Therefore, in actual use, if we cannot tolerate these two shortcomings (especially the second one), we usually tend to use babel-plugin-transform-runtime .

But if the code contains instance methods of the type in the js [1,2,3].includes(1) ), you still need to use polyfill . The picture below is the description of the official website:

image-20210817145550319.png

program:

  • Any JavaScript advanced syntax features can be well supported;
  • You can compress and obfuscate the code, reduce file size, improve static file loading performance, and improve source code security;

solution:

  • The source file needs to be modified before construction, which is relatively heavy and error-prone;
  • Need to introduce build tools, add build configuration, and possibly modify the Jenkinsfile CI script;

ESlint warning

ESlint is a plug-in javascript code detection tool. We can use it to ES6+ FM project script. If it is used in the script, immediately report an error and prompt which keywords are used in the ES6 syntax. In addition, to prevent the development of a strong push students to use ES6+ grammar code in git hooks of pre-commit execution hook in eslint command check, if passed, then the code success commit ; if not through, the console will print the error log.

Note: Please do not add --no-verify commit , otherwise the verification will be skipped

Specific landing process:

(1) Install the ESlint extension plug- VScode

(2) Create a .eslintrc.json npx eslint --init under the project root directory or the project that needs to be inspected, and add the following configuration items:

{
  "root": true,
  "env": {
    "browser": true,
    "jquery": true
  },
  "parserOptions": {
      "ecmaVersion": 5,
      "sourceType": "script"
  },
  "rules": {
  }
}

(3) package.json configuration target environment

{
    "browserslist": [
        "defaults",
        "not ie <= 8"
    ]
}

(4) because the management center does not need to support IE , therefore end on this project js not need ESlint view, we created in the root directory .eslintignore configuration file, add the path to the file which needs to skip the review, such as src/main/webapp/static/js/adjustPage.js do not need to view:

// .eslintignore
src/main/webapp/static/js/adjustPage.js

npm init in the root directory to generate package.json , install lint-staged、husky , and precommit hook to perform eslint verification git commit submit the code

  • Install lint-staged、husky
$ yarn add lint-staged husky -D
  • Generate .husky folder and pre-commit hook script
$ npx husky install // 生成.husky文件夹
$ npx husky add .husky/pre-commit 'npx lint-staged' // 添加pre-commit钩子到.husky中
Note: Because I used npx here, you need to install npm i npx -g
  • Configure package.json
// 新增如下配置
{
  "lint-staged": {
    "*.js": [
      "eslint --ignore-path .gitignore"
    ]
  }
}

At this point, execution git commit -m 'xxx' review submitted after js script, but git push when being given no change-id , because by gerrit code review need change-id , execute the following command can be solved:

scp -p -P 29418 a02313@gerrit.casstime.net:hooks/commit-msg .husky
Note: The a02313 is changed to your own

Execution effect chart:

image-20210813113825777.png

But the above configuration can only view some ES6 grammar. For fetch、includes does not support IE browser, such as api , it cannot be viewed. You need to consider prohibiting the use of fetch() such as API . In the development stage, it API . A more reliable way is to use tools to automate scanning, such as eslint-plugin-compat described below.

Use eslint-plugin-compat

eslint-plugin-compat is ESLint a widget by former uber engineer Amila Welihinda development. It can help find incompatibility API in the code.

api-compat-1.png

The following describes how to access eslint-plugin-compat in the project.

(1) Install eslint-plugin-compat

Installing eslint-plugin-compat similar to installing other ESLint plug-ins:

$ npm install eslint-plugin-compat --save-dev

(2) Modify ESLint configuration

After that, we need to modify ESLint , plus the use of the plug-in:

// .eslintrc.json
{
  "extends": ["eslint:recommended", "plugin:compat/recommended"],
  "rules": {
    //...
  },
  "env": {
    "browser": true
    // ...
  },
  // ...
}

(3) Configure the target operating environment

Configure the target operating environment by adding the browserslist field in package.json Example:

{
  // ...
  "browserslist": ["chrome 70", "last 1 versions", "not ie <= 8"]
}

The above value means Chrome version 70 , or the latest version of each browser, or not ie 8 and below. The filling format here is to follow a set of description specifications defined browserslist ( https://github.com/browserslist/browserslist browserslist is a set of tools that describe the target operating environment of the product. It is widely used in various browser/mobile compatibility support tools, such as eslint-plugin-compat 、babel、Autoprefixer . Let's take a browserslist look at the description specification of 0611cccad877c5.

browserslist supports specifying the target browser type, and can flexibly combine a variety of specified conditions.

test effect

After completing the browserslist rule, we can combine the ESLint scan the compatibility problem API in the project. At the same time, the VS Code plug-in can also prompt the incompatible API call immediately.

image-20210818093845893.png

Use eslint-plugin-builtin-compat

eslint-plugin-compat principle is an acknowledgment types and properties, use caniuse ( http://caniuse.com ) data set caniuse-db and MDN ( https://developer.mozilla.org/en-US/ data) mdn-browser-compat-data the data in API to confirm the compatibility of 0611cccad8788c. However, for uncertain instance objects, because it is difficult to judge the compatibility of the method of the instance, in order to avoid false alarms, eslint-plugin-compat chose to skip the check of API

For example, when foo.includes is not sure whether foo is an array type, it cannot determine the compatibility of the includes In the following figure, when we use the above browserslint configuration, includes method has not been scanned:

api-compat-includes-1.png

However, it can be found caniuse Array.prototype.includes() cannot be compatible with IE

image-20210817151252336.png

In order to avoid false negatives, we can combine another compatibility check plug-in eslint-plugin-builtin-compat . Also by means of the plug mdn-browser-compat-data to scan compatible with eslint-plugin-compat difference is that the plug will not miss the object instance, it will all foo.includes the includes method as is Array.prototype.includes() method to scan. It is conceivable that this plug-in may cause false positives. Therefore, it is recommended to change its alarm level to warning .

(1) Install eslint-plugin-builtin-compat

$ npm install eslint-plugin-builtin-compat --save-dev

(2) Modify ESLint configuration

Similar to eslint-plugin-compat , we can modify ESLint , plus the use of the plug-in. However, because the plug-in is prone to false alarms, it is only recommended to change its alarm level to warning :

// .eslintrc.json
{
  "extends": ["eslint:recommended", "plugin:compat/recommended"],
  "plugins": [
    "builtin-compat"
  ],
  "rules": {
    //...
    "builtin-compat/no-incompatible-builtins": 1
  },
  "env": {
    "browser": true
    // ...
  },
  // ...
}

After adding the plug-in, you can find that the Array.prototype.includes() method will be alerted by the plug-in:

image-20210818094029925.png

this program:

  • The configuration is relatively simple, no need to modify the script code, no need to modify the Jenkinsfile CI script;

the program:

  • The source code can be seen directly on the console, which is not safe;

IDEA in ESlint

In actual needs, back-end students may be responsible for part of the front-end requirements of the FM project, so they also need to meet the use of IDEA in ESlint

(1) Check node environment is eslint installed globally. If not, you need to install it. After installation, restart IDEA , and then check Enable start ESlint inspection

image-20210813163012398.png

(2) If the restart IDEA after starting eslint Service Times are wrong, because IEAD in plugins/JavaScriptLanguage/languageService/eslint version is too low, there is a plug-in compatibility issues

image-20210813163045270.png

image-20210813163626125.png

The solution is to modify the plugins/JavaScriptLanguage/languageService/eslint/bin/eslint-plugin.js file as follows, and then restart IDEA

//this.cliEngine = require(this.basicPath + "lib/cli-engine");
this.cliEngine = require(this.basicPath + "lib/cli-engine").CLIEngine;

Normal effect:

image-20210813164107066.png

In summary, if the existing project team FM project, for example, the stocking group’s mall page has been developed in multiple languages, and then the construction tools are used for packaging, such projects do not need to consider the ES6+ syntax problem, other scenarios The FM project can choose to use the second program . The plan in this article serves as a starting point, and we will analyze the specific scenarios in detail.

Organization and implementation


Feedback and suggestions

Any questions or better suggestions can be reported to XX classmates, thank you for your support and cooperation!


浪遏飞舟
1.9k 声望4.5k 粉丝