webpack常见面试题

webpack常见面试题

前端代码为何要进行构建和打包

  • 体积更小(Tree-Shaking、压缩、合并),加载更快
  • 编译高级语言或语法(TS,ES6+、模块化、scss
  • 兼容性和错误检查(Polyfill postcss eslint
  • 统一、高效得开发环境
  • 统一得构建流程和产出标准
  • 继承公司构建规范(提测、上线等)

module chunk bundle分别什么意思,有何区别

  • module-各个源码文件,webpack中一切皆模块
  • chunk-多个模块合并成的,如entry import() splitChunk
  • bundle-最终的输出文件

loaderplugin 的区别

  • loader模块转换器,如less=>css
  • plugin扩展插件,如HtmlWebpackPlugin

webpack如何实现懒加载

  • import()
  • 结合 Vue React 异步组件
  • 结合 Vue-router React-router异步加载路由

babelwebpack的区别

  • babel-js新语法编译工具,不关心模块化
  • webpack-打包构建工具,是多个loader plugin的集合

webpack 常见性能优化

babel-runtimebabel-polyfill 的区别

  • babel-runtime不会污染全局
  • babel-polyfill 会污染全局
  • 产出第三方 lib 要用 babel-runtime

为何 Proxy 不能被 Polyfill

  • Class 可以用 funcion 模拟
  • Promise 可以用 callback 模拟
  • 但是Proxy的功能用 Object.defineProperty无法模拟

webpack性能优化-构建速度

  • 优化babel-loader

  • {
        test: /\.js$/,
        loader: ['babel-loader?cacheDirectory'],//开启缓存
        include: srcPath,
        // exclude: /node_modules/
    },
    
  • IgnorePlugin

  • noParse

  • happyPack

    • JS单线程,开启多进程打包
    • 提高构建速度(特别式多核CPU
  • const HappyPack = require('happypack')
    {
        test: /\.js$/,
        // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
        use: ['happypack/loader?id=babel'],
        include: srcPath,
        // exclude: /node_modules/
    },
    
    // happyPack 开启多进程打包
    new HappyPack({
        // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
        id: 'babel',
        // 如何处理 .js 文件,用法和 Loader 配置中一样
        loaders: ['babel-loader?cacheDirectory']
    }),
    
  • ParallelUglifyPlugin

    • webpack 内置 Uglify工具压缩JS现在webpack4要换成 terser-webpack-plugin
    • JS单线程,开启多进程压缩更快
  • const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
            // 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
            new ParallelUglifyPlugin({
                // 传递给 UglifyJS 的参数
                // (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
                uglifyJS: {
                    output: {
                        beautify: false, // 最紧凑的输出
                        comments: false, // 删除所有的注释
                    },
                    compress: {
                        // 删除所有的 `console` 语句,可以兼容ie浏览器
                        drop_console: true,
                        // 内嵌定义了但是只用到一次的变量
                        collapse_vars: true,
                        // 提取出出现多次但是没有定义成变量去引用的静态值
                        reduce_vars: true,
                    }
                }
            })
    
  • 热更新

  • DLLPlugin

    • webpack已经内置DLLPlugin支持
    • DLLPlugin-打包出dll文件
    • DLLReferencePlugin-使用dll文件

webpack性能优化-产出代码

  • 体积更小
  • 合理分包,不重复加载
  • 速度更快哦,内存使用更少

小图片采用 base64

            // 图片 - 考虑 base64 编码的情况
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // 小于 5kb 的图片用 base64 格式产出
                        // 否则,依然延用 file-loader 的形式,产出 url 格式
                        limit: 5 * 1024,

                        // 打包到 img 目录下
                        outputPath: '/img1/',

                        // 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
                        // publicPath: 'http://cdn.abc.com'
                    }
                }
            },

bundle 加上 hash

    output: {
        // filename: 'bundle.[contentHash:8].js',  // 打包代码时,加上 hash 戳
        filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 key
        path: distPath,
        // publicPath: 'http://cdn.abc.com'  // 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到
    },

懒加载

提取公共代码

    optimization: {
        // 压缩 css
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],

        // 分割代码块
        splitChunks: {
            chunks: 'all',
            /**
             * initial 入口chunk,对于异步导入的文件不处理
                async 异步chunk,只对异步导入的文件处理
                all 全部chunk
             */

            // 缓存分组
            cacheGroups: {
                // 第三方模块
                vendor: {
                    name: 'vendor', // chunk 名称
                    priority: 1, // 权限更高,优先抽离,重要!!!
                    test: /node_modules/,
                    minSize: 0,  // 大小限制
                    minChunks: 1  // 最少复用过几次
                },

                // 公共的模块
                common: {
                    name: 'common', // chunk 名称
                    priority: 0, // 优先级
                    minSize: 0,  // 公共模块的大小限制
                    minChunks: 2  // 公共模块最少复用过几次
                }
            }
        }
    }

IngorePlugin

  • 忽略

使用CDN加速

publicPath: 'http://cdn.abc.com' // 修改所有静态文件 url 的前缀(如 cdn 域名)

使用production

  • 自动开启代码压缩
  • Vue React等会自动删掉调试代码(如开发环境得warning
  • 启动Tree-Shaking
    • ES6 Module才能让 tree-shaking生效
    • commonjs 就不行

ES6 Module 和 Commonjs区别

  • ES6 Module静态引入,编译时引入
  • Commonjs动态引入,执行时引入
  • 只有ES6 Module才能静态分析,实现Tree-Shaking

Commonjs

let testXzt = require('../config/api.js')
if (isDev) {
	//可以动态引入,执行时引入
	testXzt  = require('../config/api_dev.js')
} 

ES6 Module

import testXzt from '../config/api.js'
if (isDev) {
	//编译时报错,只能静态引入
	import testXzt from '../config/api.js'
}

Scope Hosting

  • 代码体积更小
  • 创建函数作用域更少
  • 代码可读性更好

babel

  • 前端开发环境必备工具

  • webpack,需要了解基本得配置和使用

babel-polyfill

  • Polyfill是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能
  • 推荐直接使用core-jsregenerator
  • babel-polyfill即俩者得集合,现在已经被弃用

你可能感兴趣的:(webpack)