• 理解前端工程化


    最初对前端的观感:眼花缭乱,各种各样的工具链以及其对应的配置文件、VS Code 插件,各种技术百家争鸣,选择众多。后来才理解前端不同于后端,后端代码的运行环境相对可控,而前端代码运行在用户设备上,所以需要兼容不同的环境,而很大一部分的工具、配置都是解决兼容性的问题

    TL;DR

    工程化的目的:降低开发成本提高开发效率
    方式:解决前端三大件(HTML, CSS, JS)存在的问题并对其进行增强,JS 通过 Babel 而 CSS 可以通过 Sass, Less, PostCSS 等工具实现进行增强,并且保证输出向后兼容的的 JS 或 CSS 代码

    模块化、包管理

    分解聚合:拆分复杂任务,降低复杂度(分而治之)

    模块化解决 问题:1. 全局污染 2. 依赖管理 等等
    JS 模块化标准(常用):1. CommonJS (Node 标准)2. ES modules(JavaScript 官方标准模块化方案)
    实现:1. 浏览器只支持 ESM 2. Node 和 构建工具 上面两种标准都支持

    包 (package) 管理:npm(Node.js的标准包管理器),还有其他的 pnpm 和 yarn 等

    JS 工具链

    JS 语言本身一直都在繁荣地发展,经常出现新的 API 和 语言特性,但是用户的运行环境(浏览器、Node等)的版本可能是五花八门的,可能会导致报错、兼容性等的问题,所以最朴素的解决方式就是把 JS 都转换为向后兼容的老版本 JS 代码。前端的运行环境更多的是在用户这边,这点不同于后端能比较自由地调整服务器运行环境,这可能就是前端缝缝补补的原因吧,修补主要有的方式:

    1. 新 API:使用 Polyfill(填充物),为其实现缺少的 API,例如 core-js 库,就实现了 ArrayflatMap 方法,这样在旧版本的 Node 环境,也可使用该方法
    2. 新语法:例如 Promise,对于这样的语法糖,就无法直接为其编写方法,需要转换代码,有点类似翻译,通过 regenerator 库可以将含有 Promise 的代码转换为向后兼容的代码

    有很多这样的库用于解决某个特定的兼容性问题,一个个导入很麻烦,所以就有了 Babel,可以通过 Babel 的插件整合这些转换代码的库,需要安装对应的 Babel 插件依赖 并在 babel.config.js 中配置 plugins。这样还是很麻烦,所以我们可以直接使用 Babel 的预设,其中最常用的就是:@babel/preset-env,安装依赖以后完成以下的 babel.config.js 配置,即可开箱即用:

    // common js
    module.exports = {
        presets: [
            // 预设名称 & 配置
            ['@babel/preset-env', {
                targets: {
                    edge: '17',
                    firefox: '60',
                    chrome: '67',
                    safari: '11.1'
                },
                // 按需导入 polyfill,未使用的 API 不导入
                useBuiltIns: 'usage',
                corejs: '3.37.0',
            }]
        ]
    
        // 插件的配置方式
        // plugins: [
        //     '@babel/plugin-transform-optional-chaining'
        // ]
    }
    

    有了这种思维之后,就可以通过 转换代码 的方式任意地增强 JS 的能力,就像:JSXTypeScript ,它们最终还是会被编译为纯 JS 代码

    CSS 工具链

    CSS 语法缺失(逻辑、函数等等),无法进行复杂的操作,所以就有了 CSS 预编译器:Less, Sass 等等的,与 JS 的处理方式一样,可以通过工具对其进行转换,转换为最朴素的 CSS,这样就没有兼容性的问题。解决了兼容性问题还需要解决 CSS 本身的问题:

    1. 浏览器前缀 ( vendor prefixes ):类似 -webkit- 开头的样式 ,可以通过 autoprefixer 来自动添加浏览器前缀以确保网页在不同浏览器中的兼容性
    2. 压缩:减少 CSS 文件的大小,从而提高网页加载速度,相关的库 cssnano
    3. 剪枝:移除没有用到的 CSS,相关的库:purgecss
    4. 类名冲突:通过 css module 来实现,相关的库:postcss-modules

    与处理 JS 的 Babel 类似,CSS 也有工具整合了上面这些工具,它就是PostCSS,安装需要的 依赖后,还需要配置 postcss.config.js。与 Babel 类似,它也可以开箱即用,需要安装依赖并配置 postcss-preset-env

    module.exports = {
      map: false,
      plugins: {
        tailwindcss: {},
        'postcss-preset-env': {},
      },
    };
    

    构建工具和脚手架

    开发和运行的代码不一致,开发阶段我们希望工程代码可以方便地开发维护,而在对于生产运行的代码,我们则希望它兼容性强、文件小、加载快等等。这中间就需要打包工具来进行转换,常用的打包工具有:webpack,它的主要作用:

    1. 模块化管理:使得项目结构清晰、依赖关系明确
    2. 打包编译:将各个模块按照其依赖关系进行打包编译,将它们转换为浏览器可识别的静态资源文件
    3. 资源优化:压缩 JavaScript、CSS、图片等文件,以减小文件体积,提高加载速度
    4. 代码分割:实现按需加载,提高页面加载性能
    5. 开发服务器:自动编译并运行服务(热更新),便于开发
    6. Source Map:存储了编译后代码与源代码之间的映射关系,便于调试代码

    BabelPostCSS 相似,一旦有很多细碎的东西出现,就必然有工具可以进行整合并提供预设,对于整个代码工程来说,它就是脚手架:vue-cli, vite 等等,提供了交互式的界面辅助生成工程模版

    参考资料

    ECMAScript 6 入门 - 阮一峰
    工程化大师课
    What is @babel/preset-env and why do I need it?
    postcss 结合 tailwindcss
    前端技术的十八年风雨(2006-2024)

  • 相关阅读:
    微服务开发,这10个点你要知道
    ADOP告诉您光分路器的类型?如何选择?
    open62541直接导入NodeSet文件
    自制快速冒烟测试小工具--基于python多线程
    丁鹿学堂前端培训:node自动化启动和模块化路由
    git的master、develop、feature分支分别是做什么用的?有什么区别和联系?
    Go 并发编程模型
    leetcode 326. 3 的幂
    扩展运算符
    当你离开现在的公司,你的百万业务量还能保持吗?
  • 原文地址:https://www.cnblogs.com/aaronlinv/p/18162050