前言
前端开发是创建WEB页面或APP等前端界面呈现给用户的过程,通过HTML,CSS及JavaScript以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。
前端作为程序员的最低门槛,近些年随着人数突增,难度也大大提升,那么作为前端开发,提升个人技术,增加个人对这个行业的竞争力就格外重要,从入门基础到框架,再到更高级的技术,掌握就可以成为除了年纪而无法替代的程序猿。
话不多说,展示一波内容,都是个人整理,需要可以【点击此处】,记得备注一下哦

目录展示
正文1. [Webpack] 配置代码太多,达到数千⾏,这个时候该如何优化配置代码【热度: 186】
当 Webpack 配置代码变得冗⻓和难以管理时,可以采取以下⽅法来优化配置:
• 配置⽂件拆分
将配置⽂件分成多个部分,每个⽂件只负责⼀部分逻辑。⽐如基础配置、开发环境配置、⽣产环境配置等。
1 // webpack.base.js - 存放共同的配置项// webpack.dev.js - 开发环境特定的配置项//webpack.prod.js - ⽣产环境特定的配置项
• 使⽤环境变量
通过环境变量来区分不同的配置环境,使⽤ webpack-merge 或 env-cmd 这样的库来合并配置。
1 // 通过环境变量确定不同的配置⽂件const env = process.env.NODE_ENV;23 let config;4 if (env === "production") {5 config = require("./webpack.prod.js");6 } else {7 config = require("./webpack.dev.js");8 }910 module.exports = config;
• 模块化配置
将常⽤的 loader、plugins、entry 等配置项封装成函数或者模块,然后在主配置⽂件中引⼊。
1 // loaders.js - 存放所有loader的配置// plugins.js - 存放所有plugins的配置//entries.js - 存放⼊⼝⽂件配置// webpack.config.jsconst loaders =require("./loaders");2 const plugins = require("./plugins");3 const entries = require("./entries");45 module.exports = {module: {6 rules: loaders.getRules(),7 },8 plugins: plugins.getPlugins(),9 entry: entries.getEntries(),// ...10 };
• 使⽤ webpack-merge 抽离通⽤配置
检查配置中的重复部分,将它们抽象成共⽤的配置, 再使⽤ webpack-merge 来合并多个配置⽂件,保持配置的清晰和可维护性。
1 const { merge } = require("webpack-merge");2 const baseConfig = require("./webpack.base.js");3 const devConfig = require("./webpack.dev.js");45 module.exports = merge(baseConfig, devConfig);
• 统⼀管理插件和加载器
如果项⽬中使⽤了⼤量插件和加载器,请考虑将它们的实例化和配置逻辑封装在单独的函数或⽂件中。 然后根据不同的环境, 直接 pick 不同的配置即可。 可以达到配置的 loader 和 plugin 集中管理。
2. [Webpack] 你⽤过哪些可以提⾼效率的插件?【热度:179】
• webpack-dashboard:可以更友好的展⽰相关打包信息。
• webpack-merge:提取公共配置,减少重复配置代码
• speed-measure-webpack-plugin:简称 SMP,分析出 Webpack 打包过程中 Loader 和 Plugin 的耗时,有助于找到构建过程中的性能瓶颈。
• size-plugin:监控资源体积变化,尽早发现问题
• HotModuleReplacementPlugin:模块热替换
• webpack.ProgressPlugin:打包进度分析
• webpack-bundle-analyzer:打包结果分析
• friendly-errors-webpack-plugin: 代码源码编译报错友好提⽰
3. 在做 eslint 和 commitlint 的时候, 可以使⽤ --no-verify跳过, 这种情况下该如何强制卡点【热度: 233】
跳过 eslint 和 commitlint 的钩⼦,使⽤ --no-verify (对于 git commit 来说是 -n ),的确是⼀个容许开发者在紧急情况下超越钩⼦检查的⼿段。然⽽,这也削弱了代码质量保证的制度。以下是⼀些⽅法,可以⽤来加强这些卡点的靠谱办法:
• CI/CD 流⽔线中增加检查:在你的 CI/CD 流程中增加 eslint 和 commitlint 的检查步骤。如果检查失败,则阻⽌代码合并或部署。
• 强制挂钩:虽然开发者可能在本地禁⽤钩⼦,但你不能控制别⼈的本地环境。相反,你可以编写服务器端的钩⼦,⽐如在 Git 仓库的服务器上使⽤ pre-receive 钩⼦,来拒绝不符合规范的提交。
• 定期⾃动化检查:定期运⾏⼀个⾃动化的脚本或 GitHub Action,检查代码库的 eslint 与commitlint 违规情况,并⾃动创建⼀个修复问题的 issue 或拉取请求。你可以最⼤限度地减少绕过 eslint 和 commitlint 检查的情况。然⽽,值得记住的是,在极少数情况下,可能存在合法的理由需要紧急提交代码。因此,为了灵活性和效率,完全禁⽌ --noverify 可能不是⼀个最佳的选择。好的实践中应该找到安全和灵活性之间的平衡,核⼼在于建⽴⼀个质量意识,制定明智的操作规范。
4. 如何做 commit lint【热度: 425】
Commit lint 是⼀种实践,⽤于在代码库中规范化提交信息的格式。这种做法通常有助于团队成员理解代码库的历史记录,以及⾃动化⽣成变更⽇志。下⾯是实施 Commit lint 的⼀些基本步骤:
1. 选择 Commit 信息规范: ⾸先,你需要选择⼀个提交信息的规范,最常⻅的是ConventionalCommits,它具有明确的结构和规则。
2. 配置 Linter ⼯具: commitlint 是⼀个流⾏的⼯具,⽤于检查提交信息是否符合规定的格式。安装commitlint,通常是作为项⽬的开发依赖。
1 npm install --save-dev @commitlint/{config-conventional,cli}
1. 设置 commitlint 配置: 在你的项⽬根⽬录下创建⼀个名为 commitlint.config.js 的⽂件,并且导⼊你选择的规范:
1 module.exports = { extends: ["@commitlint/config-conventional"] };
1. 安装钩⼦(Hook)管理⼯具: Husky 是⼀个钩⼦管理⼯具,它可以助你轻松的在 Git 挂钩中添加脚本(例如,在 commit 之前检查提交信息格式)。
1 npm install husky --save-dev
1. 配置 Husky 来使⽤ commitlint:
◦ 初始化 husky:
1 npx husky install
◦ 添加 commit-msg 钩⼦来使⽤ commitlint。执⾏⾮交互式的命令配置钩⼦脚本:
1 npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
1. 这⾏代码会在 .husky/commit-msg ⽂件中创建⼀个钩⼦,并且在你试图创建提交时,会调⽤commitlint 来检查你的提交信息。
2. 提交代码: 当你提交代码时,Husky 会触发 commit-msg 钩⼦调⽤ commitlint 检查提交信息。如果信息不符合规范,提交将被拒绝,并显⽰错误信息。
3. 配置 CI/CD 流⽔线: 为了确保规范被强制执⾏,可以在 CI/CD 流⽔线中添加⼀步来执⾏commitlint。这样,如果提交的信息不符合规范,构建将会失败。
5. 编写 npm 包的时候,可以办法⾃动⽣成 changlog 与⾃动更新 tag【热度: 455】
在编写 npm 包时,可以使⽤⾃动化⼯具来⽣成 changelog 和⾃动更新 tag。以下是你可以使⽤的⼀些流⾏的⼯具以及它们的基本⽤法。
1. semantic-release: 这是⼀个全⾃动的版本管理和包发布⼯具。它能根据 commit 信息来⾃动决定版本号、⽣成变更⽇志(changelog)以及发布。
2. 要使⽤ semantic-release,你需要按照以下步骤操作:
◦ 安装 semantic-release ⼯具:
1 npm install -D semantic-release
◦ 在项⽬中添加配置⽂件 ( semantic-release.config.js ) 或在 package.json 中配置。
◦ 在 CI ⼯具中(例如 GitHub Actions、Travis CI)配置发布脚本。
◦ 遵循规范化的 commit 消息⻛格(如 Angular 规范),因为 semantic-release 会根据 commit消息来确定版本号和⽣成 changelog。
3. standard-version: 如果你更希望进⾏半⾃动化的版本管理,standard-version 是⼀个很好的替代选择。它可以⾃动地根据 commit 记录来⽣成 changelog。
4. 使⽤ standard-version 的⼤致步骤如下:
◦ 安装 standard-version ⼯具:
1 npm install --save-dev standard-version
◦ 在 package.json 中配置脚本:
1 {2 "scripts": {3 "release": "standard-version"4 }5 }
◦ 当你准备发布新版本时,运⾏以下命令:
1 npm run release
◦ standard-version 会⾃动根据 commit 消息创建⼀个新的 tag,并更新 changelog。然后,你可以⼿动推送这些改动到仓库。
在这两种情况下,都推荐使⽤遵循某种规范的 commit 消息,如 Conventional Commits 规范,这样可以让⼯具更准确地解析 commit 消息来进⾏版本管理。此外,确保你的 CI/CD 系统有⾜够的权限来推送 tags 到远程仓库。
6. [Webpack] ts 编写的库, 在使⽤ webpack 构建的时候,如何对外提供 d.ts【热度: 224】
在 TypeScript (TS) 中使⽤ Webpack 构建并为库提供 .d.ts 类型声明⽂件,需要遵循以下步骤:
1. 配置 TypeScript 编译选项:
在库项⽬的根⽬录下创建或编辑 tsconfig.json ⽂件,确保编译器配置选项如下:
1 {2 "compilerOptions": {3 "declaration": true, // ⽣成对应的 '.d.ts' ⽂件4 "declarationDir": "types", // 指定⽣成的声明⽂件存放⽬录5 "outDir": "lib" // 指定编译后⽂件的输出⽬录6 // 其他需要的编译选项},7 "include": ["src//"], // 包含源码的⽬录8 "exclude": ["node_modules"] // 排除的⽬录9 }
◦ declaration : 这个选项会告诉 TypeScript 编译器为每个 .ts ⽂件⽣成相应的 .d.ts声明⽂件。
◦ declarationDir : 这是指定声明⽂件的输出⽬录。
1. 配置 Webpack:
在我们的 Webpack 配置中(通常是 webpack.config.js ),我们需要设置 output 以指向我们的输出⽬录,同时可能需要使⽤⼀些加载器(loader)如 ts-loader 或 babel-loader 来处理 TypeScript ⽂件。
2. ⼀个简单的 webpack 配置⽰例可能如下:
1 const path = require("path");23 module.exports = {4 entry: "./src/index.ts", // ⼊⼝⽂件module: {5 rules: [6 {7 test: /\.tsx?$/,8 use: "ts-loader",9 exclude: /node_modules/,10 },11 ],12 },13 resolve: {14 extensions: [".tsx", ".ts", ".js"],15 },16 output: {17 filename: "your-library.js", // 输出⽂件名18 path: path.resolve(__dirname, "lib"), // 输出⽂件夹19 libraryTarget: "umd", // 使库⽀持各种模块系统20 globalObject: "this",21 },22 };
1. 发布包:
当你发布你的库时,你需要确保 package.json ⽂件中包含 types 或 typings 字段指向⼊⼝ .d.ts ⽂件。
2. 例如:
1 {2 "name": "your-library",3 "version": "1.0.0",4 "main": "lib/your-library.js",5 "typings": "types/index.d.ts"6 // 其他配置项...7 }
1. 这告诉使⽤你库的 TypeScript ⽤⼾,在哪⾥可以找到类型声明⽂件。
2. 保证类型声明⽂件的发布:
如果你的 npm 发布流程排除了 types ⽬录,你需要更新 .npmignore ⽂件来确保 .d.ts⽂件会被包含在发布的 npm 包中。完成这些配置后,当你⽤ webpack 构建并发布你的库时,⽤⼾将能够获得与 JavaScript ⽂件关联的TypeScript 类型声明,以便在他们的 TypeScript 项⽬中获得类型检查和智能提⽰。
7. 测试前端代码覆盖率⼀般有什么⼿段?【热度: 550】
前端代码的测试覆盖率通常是指衡量在测试过程中有多少代码被执⾏了的⼀个指标。测试覆盖率有助于了解测试的全⾯性,以下是测试前端代码覆盖率常⽤的⼿段:
1. 单元测试:
◦ 使⽤测试框架(例如 Jest, Mocha, Jasmine 等)编写单元测试。
◦ 利⽤测试框架或插件⽣成覆盖率报告(例如 Istanbul/nyc ⼯具可以与这些框架集成以⽣成覆盖率数据)。
2. 集成测试:
◦ 使⽤测试⼯具(⽐如 Cypress, Selenium 等)编写集成测试来模拟⽤⼾操作。
◦ 通常这些⼯具也⽀持收集代码覆盖率信息。
◦
3. ⼿动测试与覆盖率⼯具结合:
◦ 在⼿动测试过程中,可以开启浏览器的覆盖率⼯具(如 Chrome DevTools 中的 CoverageTab)记录覆盖率。
◦ 可以通过浏览器扩展程序或者⾃动化脚本来启动这些⼯具。
4. 测试覆盖率服务:
◦ 使⽤像 Codecov 或 Coveralls 这样的服务,在 CI/CD 流程中集成覆盖率测试和报告。
8. [Webpack] 如何提取复⽤代码给多个 entry 使⽤?【热度:292】
在 Webpack 中提取源码⾥被多个⼊⼝点复⽤的代码,例如⼀个 utils ⽂件,可以通过配置optimization.splitChunks 来实现。Webpack 会将这些频繁复⽤的模块提取出来,打包到⼀个独⽴的 chunk 中,使得浏览器可以单独缓存这部分代码,并在多个⻚⾯间共享使⽤,优化加载性能。
使⽤ splitChunks 的基本配置如下:
1 module.exports = {// ...其他配置...2 optimization: {3 splitChunks: {4 chunks: "all", // 对所有的 chunk 有效,包括异步和⾮异步 chunk5 cacheGroups: {6 commons: {7 name: "commons", // 提取出来的⽂件命名为 'commons.js'8 chunks: "initial", // 提取出的 chunk 类型,'initial' 为初始chunk,'async' 为异步 chunk,'all' 表⽰全部 chunk9 minChunks: 2, // 模块被引⽤>=2次,便分割10 minSize: 0, // 模块的最⼩体积11 },12 },13 },14 },15 };
这个配置的含义是:
• chunks: 'all' 指定要优化的 chunk 类型,这⾥设置为 all 代表所有的 chunk,不管是动态还是⾮动态加载的模块。
• cacheGroups 是⼀个对象,⽤于定义缓存组,可以继承和/或覆盖 splitChunks 的任何选项。每个缓存组可以有⾃⼰的配置,将不同的模块提取到不同的⽂件中。
• cacheGroups.commons 定义了⼀个缓存组,专⻔⽤于提取 initial chunk(最初依赖的模块)中被⾄少两个 chunk 所共享的模块。
• name: 'commons' 为⽣成的⽂件定义了⼀个⾃定义名称。
• minChunks: 2 表⽰模块⾄少被两个⼊⼝点引⽤时,才会被提取。• minSize: 0 指定模块的最⼩体积是 0,即任意⼤⼩的模块都被提取。
这会让任何从 node_modules ⽬录导⼊,并在⾄少两个⼊⼝点中使⽤的模块,都会被打包到⼀个名为 commons.js 的⽂件中(当然,实际的⽂件名会受到 output 配置的影响,例如是否包含哈希值等)。
正确配置这些参数后, utils 这样的模块就会被⾃动提取并共享,⽽不是在每个⼊⼝点的 bundle 中重复包含。这样做的好处是,任何更新业务逻辑的时候,只要 utils 没有发⽣变化,⽤⼾浏览器上已缓存的 commons.js ⽂件就不需要重新下载。
9. [Webpack] 如何将⼀些通⽤的依赖打包成⼀个独⽴的bundle【热度: 643】
在 Webpack 中,将⼀些通⽤的依赖,如 React、React DOM、React Router 等库和框架,打包成⼀个独⽴的 bundle,通常是为了⻓期缓存和减少每次部署更新的下载量。这可以通过 "代码分割" (codesplitting) 和 "优化" (optimization) 配置来实现。
以下是 Webpack 中分离通⽤依赖的⼏个步骤:
1. 使⽤ entry 来定义不同的⼊⼝点: 可以通过配置⼀个额外的⼊⼝来创建⼀个只包含通⽤库的bundle,也就是所谓的 "vendor" bundle。
1 module.exports = {2 entry: {3 main: "./src/index.js", // 你的应⽤代码4 vendor: ["react", "react-dom", "react-router"], // 指定共享库5 },// ...6 };
1. 使⽤ SplitChunksPlugin : 这个插件可以将共享代码分割成不同的 chunks,并可以通过配置将其从业务代码中分离出来。在 Webpack 4 及之后的版本中,默认内置了optimization.splitChunks ,就是这个插件的配置⽅法。
1 module.exports = {// ...2 optimization: {3 splitChunks: {4 cacheGroups: {5 vendor: {6 test: /[\\/]node_modules[\\/]/, // 指定是 node_modules 下的第三⽅包7 name: "vendors", // 打包后的⽂件名,任意命名8 chunks: "all", // 对所有的 chunk ⽣效9 },10 },11 },12 },13 };
1. 配置 output : 虽然不是必须的,你还可以在 output 中定义 filename 和chunkFilename ,来控制主⼊⼝和⾮主⼊⼝ chunks 的⽂件名。
1 output: {2 filename: '[name].[contenthash].js',3 chunkFilename: '[name].[contenthash].js'4 }
通过这样的配置,Webpack 在打包时会⾃动将 node_modules 中的依赖和业务代码分离开来,业务代码会被打包到 main chunk 中,⽽第三⽅库则会打包到 vendors chunk。
10. [Webpack] output 配置⾥⾯, chunkFilename 和filename 区别是什么?【热度: 210】
在 Webpack 中的 output 配置对象中, filename 和 chunkFilename 是⽤来指定输出⽂件的命名⽅式的关键属性。它们之间的区别主要涉及到最终⽣成的 JavaScript ⽂件的类型。
1. filename: filename 属性⽤于指定输出的 bundle 的名称。当你的应⽤只有⼀个⼊⼝点时,可以直接使⽤⼀个固定名称。如果有多个⼊⼝点,那么你可以使⽤占位符来确保每个⽂件具有唯⼀的名称,如使⽤ [name] 来对应每个⼊⼝点的名称。 filename 主要与⼊⼝点相关联的那些⽂件有关。
1 output: {2 filename: "bundle.js"; // ⼀个固定名称,适⽤于单⼊⼝// 或者3 filename: "[name].bundle.js"; // 使⽤占位符,适⽤于多⼊⼝4 }
1. chunkFilename: chunkFilename 属性⽤于指定⾮⼊⼝的 chunk(通常是动态加载的模块)的名称。这些 chunk ⽂件通常是由于代码分割产⽣的。当使⽤如 import() 这样的动态导⼊语法时,Webpack 会分割代码到新的 chunk 中,这时候 chunkFilename 的命名规则就会被应⽤。
1 output: {2 chunkFilename: "[name].chunk.js";3 }
这意味着如果你有⼀个动态加载的模块(例如
使⽤这两个属性使得 Webpack 能够区分出⼊⼝⽂件和其他类型的⽂件,从⽽允许开发者更好地控制输出资源的命名和缓存。
11. [Webpack] 多⼊⼝打包共享模块【热度: 337】
默认情况下,每个⼊⼝ chunk 保存了全部其⽤的模块(modules)。使⽤ dependOn 选项你可以与另⼀个⼊⼝ chunk 共享模块:
1 module.exports = {//...2 entry: {3 app: { import: "./app.js", dependOn: "react-vendors" },"react-vendors":["react", "react-dom", "prop-types"],4 },5 };
app 这个 chunk 就不会包含 react-vendors 拥有的模块了.dependOn 选项的也可以为字符串数组:
1 module.exports = {//...2 entry: {3 moment: { import: "moment-mini", runtime: "runtime" },4 reactvendors: { import: ["react", "react-dom"], runtime: "runtime" },5 testapp: {import: "./wwwroot/component/TestApp.tsx",6 dependOn: ["reactvendors", "moment"],7 },8 },9 };
此外,你还可以使⽤数组为每个⼊⼝指定多个⽂件:
1 module.exports = {//...2 entry: {3 app: { import: ["./app.js", "./app2.js"], dependOn: "react-vendors"},"react-vendors": ["react", "react-dom", "prop-types"],4 },5 };
看⼀个完整案例
1 module.exports = {//...2 entry: {3 home: "./home.js",4 shared: ["react", "react-dom", "redux", "react-redux"],5 catalog: {import: "./catalog.js",6 filename: "pages/catalog.js",7 dependOn: "shared",8 chunkLoading: false, // Disable chunks that are loaded on demand and puteverything in the main chunk.9 },10 personal: {import: "./personal.js",11 filename: "pages/personal.js",12 dependOn: "shared",13 chunkLoading: "jsonp",14 asyncChunks: true, // Create async chunks that are loaded on demand.15 layer: "name of layer", // set the layer for an entry point16 },17 },18 };
12. [Webpack] 如何使⽤ ts 来编写配置⽂件?【热度: 251】
要使⽤ Typescript 来编写 webpack 配置,你需要先安装必要的依赖,⽐如 Typescript 以及其相应的类型声明,类型声明可以从 DefinitelyTyped 项⽬中获取,依赖安装如下所⽰:
npm install --save-dev typescript ts-node @types/node @types/webpack
如果使⽤版本低于 v4.7.0 的 webpack-dev-server,还需要安装以下依赖
npm install --save-dev @types/webpack-dev-server
完成依赖安装后便可以开始编写配置⽂件,⽰例如下:
webpack.config.ts
1 importas path from "path";2 importas webpack from "webpack";3 // in case you run into any typescript error when configuring devServerimport"webpack-dev-server";45 const config: webpack.Configuration = {6 mode: "production",7 entry: "./foo.js",8 output: {9 path: path.resolve(__dirname, "dist"),10 filename: "foo.bundle.js",11 },12 };1314 export default config;
该⽰例需要 typescript 版本在 2.7 及以上,并在 tsconfig.json ⽂件的 compilerOptions 中添加 esModuleInterop 和 allowSyntheticDefaultImports 两个配置项。
值得注意的是你需要确保 tsconfig.json 的 compilerOptions 中 module 选项的值为commonjs ,否则 webpack 的运⾏会失败报错,因为 ts-node 不⽀持 commonjs 以外的其他模块规范。
你可以通过三个途径来完成 module 的设置:
• 直接修改 tsconfig.json ⽂件
• 修改 tsconfig.json 并且添加 ts-node 的设置。
• 使⽤ tsconfig-paths
第⼀种⽅法就是打开你的 tsconfig.json ⽂件,找到 compilerOptions 的配置,然后设置target 和 module 的选项分别为 "ES5" 和 "CommonJs" (在 target 设置为 es5 时你也可以不显⽰编写 module 配置)。
第⼆种⽅法 就是添加 ts-node 设置:
你可以为 tsc 保持 "module": "ESNext" 配置,如果你是⽤ webpack 或者其他构建⼯具的话,为 ts-node 设置⼀个重载(override)。ts-node 配置项
1 {2 "compilerOptions": {3 "module": "ESNext"4 },5 "ts-node": {6 "compilerOptions": {7 "module": "CommonJS"8 }}9 }
第三种⽅法需要先安装 tsconfig-paths 这个 npm 包,如下所⽰:
1 npm install --save-dev tsconfig-paths
安装后你可以为 webpack 配置创建⼀个单独的 TypeScript 配置⽂件,⽰例如下:tsconfig-for-webpack-config.json
1 {2 "compilerOptions": {3 "module": "commonjs",4 "target": "es5",5 "esModuleInterop": true6 }7 }
提⽰ts-node 可以根据 tsconfig-paths 提供的环境变量 process.env.TS_NODE_PROJECT 来找到 tsconfig.json ⽂件路径。
process.env.TS_NODE_PROJECT 变量的设置如下所⽰:
package.json
1 {2 "scripts": {3 "build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json.webpack"4 }5 }
之所以要添加 cross-env ,是因为我们在直接使⽤ TS_NODE_PROJECT 时遇到过"TS_NODE_PROJECT" unrecognized command 报错的反馈,添加 cross-env 之后该问题也似乎得到了解决
13. [Webpack] 内部执⾏原理【热度: 668】
这部分可以直接转官⽹,官⽹讲得⾮常好:https://www.webpackjs.com/concepts/under-the-hood/
14. [Webpack] 为何不⽀持 CMD 模块化【热度: 255】
1. CMD 是国内产品, webpack 是国外产品, ⽽且 CMD 还没有⽕起来的时候, 就已经被 ESM 替代了
2. CMD 是更加
CMD(Common Module Definition)是⼀种深受国内前端开发者喜爱的模块定义规范,主要被⽤在了 Sea.js 这个模块加载器中。CMD 是国内开发者提出的规范,它和 AMD 很相似,但是更符合国内开发者的习惯,需要时可以延迟执⾏。
Webpack 本⾝是围绕 NPM ⽣态和标准化模块格式(如 ES Modules 和 CommonJS)构建的,⽽NPM ⽣态主要使⽤的是 CommonJS 形式。因此,对于⼤多数使⽤ NPM 之 Webpack 的⽤⼾来说,这些就⾜够⽤了。⽽ ES Modules 作为 JavaScript 官⽅的模块系统标准,越来越多地在现代应⽤中被采⽤。
⾯对 CMD,Webpack 的社区并没有⼴泛地采⽤或者需要⽀持这种模块定义。CMD 在模块定义时依赖于具体的 API 和加载时机,这和 Webpack 的理念以及模块收集和打包机制不完全兼容。Webpack ⿎励在编译时就确定模块依赖,⽽ CMD 更倾向于运⾏时动态确定。
尽管如此,理论上是可以通过⼀些插件或 loader 来实现对 CMD 模块的⽀持的,但是官⽅并没有集成这样的功能,因为需求没有那么⼤,同时现有的模块加载机制已经可以满⾜绝⼤多数场景的需要。随着前端⼯程化的深⼊,标准化的模块定义(如 ES Modules)更加受到⻘睐,⽽特定的模块定义(如CMD)则逐渐被边缘化。因此,Webpack 没有默认⽀持 CMD,也反映了当前前端模块化开发的趋势和实践。
15. [Webpack] ⽀持哪些模块化加载?【热度: 154】
Webpack ⽀持以下⼏种模块化标准:
1. ESM (ECMAScript Modules): 这是 JavaScript ES6 中引⼊的官⽅标准模块系统。使⽤ import和 export 语句来导⼊和导出模块。
2. CommonJS: 主要⽤于 Node.js,允许使⽤ require() 来加载模块和 module.exports 来导出模块。
3. AMD (Asynchronous Module Definition): ⽤于异步加载模块,并使⽤ define ⽅法来定义模块。
4. UMD (Universal Module Definition): 结合了 AMD 和 CommonJS 的特点,并⽀持全局变量定义的⽅式,使得模块可以在客⼾端和服务端上运⾏。
除此之外,Webpack 还可以处理⾮ JavaScript ⽂件并将它们视为模块,例如 CSS, LESS, SASS, 图像⽂件(PNG, JPG, GIF, SVG 等), 字体(OTF, TTF, WOFF, WOFF2, EOT), HTML 以及任何其他类型的⽂件。
这通过使⽤相应的 loader 来实现,如 style-loader , css-loader , file-loader 等。这些 loader 会将⾮ JavaScript ⽂件转换为可以被 Webpack 处理的模块。
16. 前端视⻆ - 如何保证系统稳定性【热度: 566】
前端视⻆来做稳定性, 本是⼀个开放性话题,这⾥没有统⼀的解法, 作者在此提供⼏个思路和反向:
1. 静态资源多备份(需要有备份)
2. ⾸屏请求缓存
3. 请求异常报警
4. ⻚⾯崩溃报警
5. E2E 定时全量跑⽤例
17. webpack 的主要配置项有哪些【热度: 766】
Webpack 是⼀个现代 JavaScript 应⽤程序的静态模块打包器。配置⽂件名通常为webpack.config.js ,它提供了⼀种配置 Webpack 的⽅式。下⾯是⼀些主要的 Webpack 配置选项:
1. entry: ⼊⼝起点(entry point)指⽰ webpack 应该使⽤哪个模块,来作为构建其内部依赖图的开始。可以指定⼀个或多个⼊⼝起点。
2. output: output 属性告诉 webpack 在哪⾥输出它所创建的 bundles,以及如何命名这些⽂件,默认值为 ./dist 。
3. module: module 属性⽤于决定如何处理项⽬中的不同类型的模块。
◦ rules: 配置模块的读取和解析规则,通常⽤来配置 loader。
4. resolve: 配置模块如何解析。
◦ extensions: ⾃动解析确定的扩展,此选项能够使⽤⼾在引⼊模块时不带扩展。
5. plugins: 插件是⽤来扩展 webpack 功能的。它们会在构建流程中的特定时机注⼊运⾏逻辑来改变构建结果或做你想要的事情。
6. devServer: 通过来⾃ webpack-dev-server 的这些选项能够对开发服务器的⾏为进⾏控制。
7. devtool: 此选项控制是否⽣成,以及如何⽣成 source map。
8. mode: 通过设置 development 或 production 之中的⼀个,来为流程提供相应模式下的内置优化。
9. optimization: 包含⼀组可⽤来调整构建输出的选项。
◦ splitChunks: 配置模块的拆分,可以将公共的依赖模块提取到已有的⼊⼝ chunk 中,或者提取到⼀个新⽣成的 chunk。
◦ runtimeChunk: 为每个 entry 创建⼀个运⾏时⽂件。
10. performance: 允许 webpack 根据某些参数,控制资产和⼊⼝起点的最⼤⼤⼩。
11. externals: 防⽌将某些 import 包(package)打包到 bundle 中,⽽是在运⾏时(runtime)再去从外部获取这些扩展依赖。
每个项⽬的具体需求不同,Webpack 的配置也会有所不同。这些选项提供了强⼤的配置能⼒和灵活性,可以⽤来定制 Webpack 的打包、加载和转换⾏为。
19. [webpack] optimize 配置有哪些作⽤【热度: 280】
Webpack 的 optimize 选项是在指定 Webpack 配置对象时,⽤于配置优化选项的⼀个属性。该属性下包含了⼀系列⽤于调整构建输出质量和性能的设置。这⾥是⼀些 optimize 属性中可能包含的选项:
• splitChunks:这⽤于代码分割,可以将公共的依赖模块提取到已有的⼊⼝ chunk 中,或者产⽣⼀个新的 chunk。这可以被⽤来得到更⼩的 bundle 体积,优化加载时间,或者更好的缓存利⽤。
• runtimeChunk:该选项将 Webpack 的运⾏时代码分割成⼀个单独的 chunk。使⽤这个设置有利于⻓期缓存,并且当你使⽤多个⼊⼝点时推荐使⽤。
• minimize:当设置为 true 时,Webpack 会启动代码压缩。通常,这会使⽤ UglifyJSPlugin 来进⾏ JavaScript 代码的压缩,但现在通常默认使⽤更现代的⼯具如 TerserPlugin。
• minimizer:当你想要覆盖默认的压缩⼯具或者提供额外的压缩⼯具时使⽤。
• noEmitOnErrors(早期版本称为 NoEmitOnErrorsPlugin ):启⽤该选项后,Webpack 编译错误将会导致不⽣成输出。这确保了不会发出包含错误的 assets。
• concatenateModules(早期版本称为 ModuleConcatenationPlugin ):这个选项会试图找到模块图中可以安全地连接到单⼀模块的所有模块,来优化结果的体积。
• usedExports(也称为 tree shaking):该选项⽤于标记 "tree shaking" 中未被使⽤的导出,使它们能被压缩⼯具删除。
在 Webpack 4 及以上版本中,这些优化默认在 mode 被设置为 production 时⽣效。通过合理地配置这些选项,开发者可以显著提⾼应⽤程序的加载和运⾏性能。这些优化通常包括减少 bundle 的体积和提⾼代码的运⾏时效率。在开发模式下,很多优化默认是关闭的,以提供更快的构建速度和更好的调试体验。
21. V8 ⾥⾯的 JIT 是什么?【热度: 694】
在计算机科学中,JIT 是“Just-In-Time”(即时编译)的缩写,它是⼀种提⾼代码执⾏性能的技术。
具体来说,在 V8 引擎(Google Chrome 浏览器和 Node.js 的 JavaScript 引擎)中,JIT 编译器在JavaScript 代码运⾏时,将其编译成机器语⾔,以提⾼执⾏速度。
这⾥简要解释下 JIT 编译器的⼯作原理:
1. 解释执⾏:V8 ⾸先通过⼀个解释器(如 Ignition)来执⾏ JavaScript 代码。这个过程中,代码不会编译成机器语⾔,⽽是逐⾏解释执⾏。这样做的优点是启动快,但执⾏速度较慢。2. 即时编译:当代码被多次执⾏时,V8 会认为这部分代码是“热点代码”(Hot Spot),此时 JIT 编译器(如 TurboFan)会介⼊,将这部分热点代码编译成机器语⾔。机器语⾔运⾏在 CPU 上⽐解释执⾏要快得多。
3. 优化与去优化:JIT 编译器会对热点代码进⾏优化,但有时候它会基于错误的假设做出优化(例如认为某个变量总是某种类型)。如果后来的执⾏发现这些假设不成⽴,编译器需要去掉优化(Deoptimize),重新编译。
JIT 编译器的⼀个关键优点是它能够在不牺牲启动速度的情况下,提供接近于或同等于编译语⾔的运⾏速度。这使得像 JavaScript 这样原本被认为执⾏效率较低的语⾔能够⽤于复杂的计算任务和⾼性能的应⽤场景。
随着 V8 和其他现代 JavaScript 引擎的不断进步,JIT 编译技术也在持续优化,以提供更快的执⾏速度和更⾼的性能。
结尾目前来说前端工程化还是一种对标高级的技术,掌握之后涨薪加位,但也要各位能掌握一定的技术再去了解,不然总不能还不会走就想跑吧!
今天的分享就到这里,如果有以下需求可【点击此处】不要忘记备注
1.前端面试八股合集
2.前端2024最新场景题合集
3.前端工程化面试合集
4.前端面试简历模板(轻松修改简历)
5.前端面试算法合集
6.前端项目疑难点以及相关内容
7.前端中大厂面经合集