面试记录专刊:第7天

175 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

今日复习计划:webpack的优化、类、typescript infer。

一.前端知识

1. webpack的优化

当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

1.1 缩小文件搜索范围

优化Loader查找范围

test include exclude三个配置都可以缩小webpack查找范围,推荐使用includeexclude优先级较高。

//string
include: path.resolve(__dirname, "./src"),

//array
include: [
  path.resolve(__dirname, 'app/styles'),
  path.resolve(__dirname, 'vendor/styles')
]

优化resolve.modules

resolve.modules可以用于配置webpack寻找三方依赖的目录。通过直接指定根目录下node_modules可以优化查询。

module.exports={
resolve:{
   modules: [path.resolve(__dirname, "./node_modules")]
   }
}

优化resolve.alias

优化别名指向,直接指向依赖umd

alias: {

    "@": path.join(__dirname, "./pages"),
    react: path.resolve(
    __dirname,
    "./node_modules/react/umd/react.production.min.js"
    ),
    "react-dom": path.resolve(
    __dirname,
    "./node_modules/react-dom/umd/react-dom.production.min.js"
    )
}

优化resolve.extensions

webpack在处理导入时,如导入文件没有后缀,则会自动带上后缀,去尝试查找文件是否存在。 默认值:

extensions:['.js','.json','.jsx','.ts']

代码优化:

import a from 'a'  // webpack需要匹配后缀去查找文件是否存在

import a from 'a.js' // 无需匹配后缀,直接查找
1.2 提高构建速度

thread-loader

将高开销的loader放进worker池里运行。

module.exports = {
    module: {
    rules: [
    {
      test: /\.js$/,
      include: path.resolve('src'),
      use: [
     'thread-loader'
      // 你的⾼开销的loader放置在此 (e.g babel-loader)
       ]
     }
     ]
    }
};

开启cache缓存
babel-loader 在执⾏的时候,可能会产⽣⼀些运⾏期间重复的公共⽂件,造成代码体积⼤冗余,同时也会减慢编译的速度。babel-loader 提供了cacheDirectory配置给 Babel 编译时给定的⽬录,并且将⽤于缓存加载器的结 果,但是这个设置默认是 false 关闭的状态,我们需要设置为 true ,这样 babel-loader 将使⽤默认的 缓存⽬录

rules: [
 {
  test: /\.js$/,
  loader: 'babel-loader',
  options: {
    cacheDirectory: true
   },
 }
];

压缩速度优化

使用terser-webpack-plugin在生产环境打包时,可以通过开启缓存以及多线程,提高压缩效率:

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  optimization: {
  minimizer: [
   new TerserPlugin({
     cache: true, // 开启缓存
     parallel: true // 多线程
   })
  ]
 }
};

externals优化CDN资源

//webpack.config.js
module.exports = {
externals: {
  //jquery通过script引⼊之后,全局中即有了 jQuery 变量
  'jquery': 'jQuery' 
  }
}

CDN资源优化

output:{
  publicPath: '//cdnURL.com', //指定存放JS⽂件的CDN地址
}
1.3 CSS压缩

optimize-css-assets-webpack-plugin 是⼀个 CSS 的压缩插件,默认的压缩引擎就是 cssnano。 Webpack 中配置:

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
new OptimizeCSSAssetsPlugin({
  cssProcessor: require("cssnano"), // 这⾥制定了引擎,不指定默认也是 cssnano
  cssProcessorOptions: {
    discardComments: { removeAll: true }
  }
})
1.4 压缩HTML

借助html-webpack-plugin

new htmlWebpackPlugin({
  title: "京东商城",
  template: "./index.html",
  filename: "index.html",
  minify: {
    // 压缩HTML⽂件
    removeComments: true, // 移除HTML中的注释\
    collapseWhitespace: true, // 删除空⽩符与换⾏符
    minifyCSS: true // 压缩内联css
}
}),
1.5 树抖JS及CSS

JS tree-shaking

mode = production下,webpack会自动压缩JS代码。推荐使用terse来自定义压缩工具:

const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
  optimization: {
   minimizer: [new TerserPlugin(
     parallel: true // 多线程
  )],
  }
};

css tree-shaking 使用purifycss-webpack实现:

plugins:[
// 清除⽆⽤ css
  new PurifyCSS({
    paths: glob.sync([
    // 要做 CSS Tree Shaking 的路径⽂件
      path.resolve(__dirname, './src/*.html'), // 请注意,我们同样需要对 html ⽂
      件进⾏ tree shaking
      path.resolve(__dirname, './src/*.js')
    ])
})
]

2. 类的继承

super

super可用作函数,也可用作对象。

class A {
  constructor() {
    this.log1 = () => {
      console.log("aaalog1");
    };
  }
  log2 = () => {
    console.log("aaalog2");
  };
}

class B extends A {
  constructor() {
    super();
    this.log1 = () => {
      console.log("bbblog1");
    };
    super.log2 = ()=>{
      console.log("bbblog2");
    }
  }
}

let b = new B();
b.log1();  // bbblog1
b.log2();  // bbblog2

需要注意的是,superthis指向为子类。

class A {
  constructor() {
    this.name = "a";
    this.log = function () {
      console.log(this.name);
    };
  }
}

class B extends A {
  constructor() {
    super();
    this.name = "b";
    this.log = function () {
      console.log(this.name);
    };
  }
}

let a = new A();
a.log();  // a
let b = new B();
b.log();  // b

子类的__proto__属性,表示构造函数的继承,总是指向父类。子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

3. typescript infer

extends语句中,infer可以准确表示一个类型变量。但只能在true分支中使用。

type Cloumns<T> = T extends { [key: string]: any } ? T[] : any;

二.算法

二叉树的最大深度

翻转二叉树

三.面经

四.其他

There is only one heroism in the world: to see the world as it`s and to love it