前端- 工程化

前端- 工程化

一般包括

  1. 前端库/框架选型 ,eg vue, react,angular , angularjs
  2. 构建工具, eg gulp, grunt
  3. 模块化工具 , webpack , js module (amd、commonjs etc), css 预处理器
  4. 其他 代码风格(formater, lint etc..),单元测试,自动化测试,
  5. 性能, 例如window.performance

bundle

When we write our code, we like to keep it in nice, disparate files to make it easier to read, manage, and update. But for the end browser, loading 1,000 files is not as efficient as loading, say, 4 or 5 files。bundles all the application and library files into a few bundles to make it faster to load in the browser.

minification

Minification is the process of minimizing code and markup in your web pages and script files. It’s one of the main methods used to reduce load times and bandwidth usage on websites.

Uglification

replacing all nice, readable variable and function names with a smaller, two or three character name to save a few bytes. The overall code is much more efficient and smaller to load.

polyfills VS Transpilling

Both approaches serve the same purpose: You can write code, that uses some features, which are not yet implemented in your target environment. They do this, however, by using different techniques.

A polyfill will try to emulate certain APIs, so can use them as if they were already implemented.

A transpiler on the other hand will transform your code and replace the respective code section by other code, which can already be executed.

Typically you use a polyfill, if your target browser did not yet implement the latest bleeding edge feature (read browser APIs) you want to use. A transpiler on the other hand will let you use language features, the target environment does not support yet, e.g. some ES6 features like fat arrow functions.

https://stackoverflow.com/questions/31205640/what-is-the-difference-between-polyfill-and-transpiler


tools

gulp vs grunt

主要解决前端工程自动化处理的任务 ,eg

  • Compiling Less/Sass to CSS
  • Concatenating and minifying CSS and JavaScript
  • Linting code
  • Optimizing images
  • Running unit tests
  • Much more…

webpack

At its core, webpack is a static module bundler for modern JavaScript applications.

主要是通过Webpack loaders and Webpack plugins.

Core Concept

  • entry
  • output
  • loader
  • plugin

Entry: An entry point indicates which module webpack should use to begin building out its internal

Output: The output property tells webpack where to emit the bundles it creates and how to name these files.

loader : webpack enables use of loaders to preprocess files.

plugin: While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.

loaders

eg tsloader (TSC - typescript complier): transpile TypeScript to JavaScript


// loaders
module: {
rules: [
{
test: /\.tsx?/,
use: 'ts-loader',
exclude: /node_modules/,
}
]
}

Eg babelloader : Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments


module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}
]
},

webpack dev server

webpack 将我们的项目源代码进行编译打包成可分发上线的静态资源,在开发阶段我们想要预览页面效果的话就需要启动一个服务器伺服 webpack 编译出来的静态资源。webpack-dev-server 就是用来启动 webpack 编译、伺服这些静态资源,

sample

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
</head>
<body>
<h3>Webpack Test</h3>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>

webpack.config.js

const path = require('path');
module.exports = {
mode: 'development',
devtool: "source-map",
entry: path.join(__dirname, 'app', 'main.js'),
output: {
path: path.join(__dirname, '/public'),
publicPath: '/',
filename: "bundle.js",
},
devServer: {
contentBase: path.join(__dirname, '/public'),
inline: true,
host: 'localhost',
port: 8080,
},
module: {
rules: [{
test: /.js?$/,
include: [
path.resolve(__dirname, 'app')
],
exclude: [
path.resolve(__dirname, 'node_modules')
],
loader: 'babel-loader',
}]
}

};

App/main.js


const greet = require('./greeting');

document.querySelector('#root').appendChild(greet());

let print = v => {
console.log(v);
}

print('hello babel');

App/greeting.js


module.exports = function () {
var greet = document.createElement('div');
greet.textContent = "Hi there!";
return greet;
}

babel

Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments

Screen Shot 2021-01-01 at 10.34.24 PM

preset

preset: babel 插件集合的预设,包含某些插件 plugin. @babel/preset-env ,@babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s).

sample

.babelrc 存放配置文件,将src的js (包含es6语法)转换低版本js

CLI "build": "babel src -d js" (package.json)

index.html


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Babel</title>
</head>
<body>
<h1>BabelTest</h1>

<script src="./js/main.js"></script>
</body>
</html>

src/main.js



let print = v => {
console.log(v);
}

print('hello babel');

js/main.js (babel 转换后)

"use strict";

var print = function print(v) {
console.log(v);
};

print('hello babel');

.babelrc

{
"presets": ["@babel/preset-env"]

}

Testing

  • jasmin/jest
  • Karma

Jasmine

Jasmine is a JavaScript testing framework that supports a software development practice called Behaviour-Driven Development, or BDD for short. It’s a specific flavour of Test-Driven Development (TDD).


function helloWorld() {
return 'Hello world!';
}

describe('Hello world', () => { (1)
it('says hello', () => { (2)
expect(helloWorld()) (3)
.toEqual('Hello world!'); (4)
});
});


Screen Shot 2021-01-01 at 10.56.10 PM

Jasmine feature:

  • Async support
  • Built-in mater
  • mock and spy

jasmin vs jest

Screen Shot 2021-01-01 at 10.58.22 PM

karma

Karma is a tool which lets us spawn browsers and run Jasmine tests inside of them all from the command line. The results of the tests are also displayed on the command line.Karma can also watch your development files for changes and re-run the tests automatically.

config

module.exports = (config) => {
const coverage = config.singleRun ? ['coverage'] : [];

config.set({
frameworks: [...],
plugins: [ ... ],
files: [ ... ],
preprocessors: { ... },

webpack: { ... },

reporters: [ ... ],
coverageReporter: { ... },

port: 9999,
browsers: ['Chrome'], // Alternatively: 'PhantomJS'
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
captureTimeout: 6000,
});
};

karma launcher - http://karma-runner.github.io/5.2/config/browsers.html

由于一般ut 需要在CI 上run, 因此通常需要headless的launcher (或者xvfb https://en.wikipedia.org/wiki/Xvfb)

  • PhantomJS 已经停止维护,不建议

  • Headless Chromium puppeteer

https://medium.com/@alexbainter/replace-phantomjs-with-headless-chromium-for-javascript-unit-testing-in-karma-59812e6f8ce4


code style

code style guide : eg angularjs / angular https://github.com/johnpapa/angular-styleguide

https://khalilstemmler.com/blogs/tooling/prettier/

https://khalilstemmler.com/blogs/typescript/eslint-for-typescript/

linting

ESLint is a JavaScript linter that enables you to enforce a set of style, formatting, and coding standards for your codebase. It looks at your code, and tells you when you're not following the standard that you set in place.

https://eslint.org/docs/user-guide/getting-started

prettier

Prettier is an opinionated (yet fully configurable) code formatter. ESLint can kind of format code too, but it's mostly intended to sniff out when we're not following the mandated coding conventions.