首页
更多应用
Search
1
修改iview的标签为i-的形式而不是驼峰的形式
2,733 阅读
2
PHP微信和企业微信签名
2,423 阅读
3
在VUE中怎么全局引入sass文件
2,176 阅读
4
vscode硬件占用较高解决方案
1,910 阅读
5
解决Macos下storm系列IDE卡顿的问题
1,859 阅读
默认分类
JS
VUE
CSS
mac使用技巧
React
fastmock
登录
/
注册
Search
标签搜索
react
js
vue
nodejs
vscode
项目
代码
webpack
工具
nginx
小程序
css
fastmock
http
vue-cli3
eslint
git
浏览器
const
true
fastmock技术社区
累计撰写
95
篇文章
累计收到
9
条评论
首页
栏目
默认分类
JS
VUE
CSS
mac使用技巧
React
fastmock
页面
更多应用
搜索到
26
篇与
的结果
前端性能优化之webpack打包优化
前端工程化彻底盛行的今天,我们已经习惯使用打包工具来帮助我们打包代码到最终能在浏览器运行的js或者css代码,这样我们就可以在编写代码时放心地使用所有的高级语法,其中最让前端coder感到爽快的就是 import export,我们不再需要像以前一样在html里面放很多很多script。或者使用amd。cmd,requirejs工具来写模块引用的代码,这些方便,也让我们很容易忽略一个问题,就是打包的产物的大小,当一个项目足够大时,我们的js甚至可以达到几MB到几十MB,所以,今天就来总结下关于减小构建产物体积,来达到减少首屏加载时间的内容webpack 官方自带的优化策略 https://www.webpackjs.com/configuration/optimization/这里以react项目为例,列举需要优化的构建项一、使用代码拆分,让我们的页面代码构建到单独的js,首次访问页面的时候才加载这块jsmodule.exports = { optimization: { { usedExports: true, concatenateModules: false, chunkIds: 'deterministic', runtimeChunk: true, // 将运行时依赖单独打包-运行时依赖如我们使用的async await语法所需的降级兼容代码 设置为 'single' 则所有的runtime依赖打包到一个文件 // 使用代码拆分 参考文档 https://www.51cto.com/article/689344.html splitChunks: { chunks: 'async', // webpack 打包chunk分为 entry chunk 和async chunk两种,配置文件中的entry配置的主包是默认拆分的,多个入口,多个 main chunk。async chunk就是使用import('./xxx.js') 一步模块加载方法加载的模块。那么 chunks选项就是指定这两种chunk哪些需要分包的,`initial` 只分包主包, async 只分包异步加载的包。all 分包上面两种包,这里要注意的就是all有时候会理解成“所有”就会以为所有使用了import './xxx.js'引入的包都会被分包 minSize: 20, // 超过了这个大小的包才会被拆分 minRemainingSize: 0, minChunks: 1, // 被引用次数大于这个数的包才会被拆分,这里要注意的是,被引用是只命中entry chunk 和 async chunk 的引用者才算 maxAsyncRequests: 30, maxInitialRequests: 30, enforceSizeThreshold: 100, // 超过这个大小的包,不管有没有命中上面的配置,都分包 // 对指定规则的文件使用特定的分包策略 cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, // 匹配文件路径 type:/\.json$/, // 匹配文件类型 idHint:'vendors',// 用于设置 Chunk ID,它还会被追加到最终产物文件名中,例如 idHint = 'vendors' 时,输出产物文件名形如 vendors-xxx-xxx.js minChunks: 1, minSize: 0, priority: 2 // 设置优先级,如果文件命中多个groups策略,优先使用这个配置数字较大的规则组 } } } } } }接下来,在react路由里,将组件引入代码 import Xxxx from '@src/routes/Xxxx' 修改为如下引用方式//该组件是动态加载的 千万注意,因为组件是动态加载的,那么。就有可能出现加载失败或者加载错误的情况,所以需要使用 Suspense 组件来包裹,组件还未加载,显示fallback中的内容,组件加载完成,显示组件,加载失败会throw一个error,防止页面崩溃 const Home = React.lazy(() => import('./Home')); function Layout() { return ( // 显示 <Spinner> 组件直至 Home 加载完成 <React.Suspense fallback={<Spinner />}> <div> <Home /> </div> </React.Suspense> ); }上面的分包策略的理解注释中的内容提到了分包的条件和规则,那么,为了尽可能减小我们的主包的大小,我们就要尽可能减少在我们的 entry 选项中指定的入口文件中对其他模块的引用,或者使用异步模块引用的方式,常见的几个优化项目为优化使用到的工具的引用,将必要的工具引用单独提到一个文件中,避免打包其他没用到的代码到主包有些应用初始化相关但是跟主应用无关的代码,使用异步模块加载,如下// app.ts (async () => { const {default: AppInit} = await import('./app-init'); aegis = AppInit.tam(); AppInit.dataInsight(); AppInit.chunkError(); })();如果在入口文件中有react或者vue路由使用的组件,使用react或vue提供的异步路由方法引入使用二、将三方库通过CDN引入而不打包到我们的代码包默认情况下,我们一般都会将我们所需要的依赖,例如react,moment,axios等三方包通过npm或yarn安装到本地,然后直接import进来使用,这种方式势必就会将这些第三方包打包到我们自己的js中,且因为这些库本身体积就较大,所以会导致我们打包出来的js非常大,而且,当我们使用了chunk切分后,各个chunk都会单独打包进去这些依赖内容。针对这种情况,webpack提供了 externals 选项来让我们可以从外部获取这些扩展依赖,首先,我们需要通过script标签的形式来引入我们需要使用的三方库,有两种方式,一种是手动在 html-webpack-plugin 的html模板文件或者content内容中加入script标签,第二种是使用html-webpack-tags-plugin插件,通过配置的方式往html内容中动态插入script标签,这里推荐后者,原因是方便写判断逻辑,而不是在html中通过ejs模板语法来写判断逻辑然后,配置externals选项告诉webpack当我们使用import语句导入模块时,实际使用的是是什么内容(一般三方库都会导出一个包含了所有他包含内容的全局变量)const assetsPath = 'https://static.xxx.com/js'; module.exports = { externals: isDev ? {} : { // 排除不打包 'react': 'React', 'react-dom': 'ReactDOM', 'react-router': 'ReactRouter', 'react-router-dom': 'ReactRouterDOM', 'axios': 'axios', 'moment': 'moment', 'moment-timezone': 'moment', 'lodash': '_', }, plugins: [ ...config.plugins, new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn|ja|ko/), new webpack.DefinePlugin(envKeys), // 开发环境不使用这种方式,因为会影响本地开发的热更新 new HtmlWebpackTagsPlugin({ tags: isDev ? [] : [ { type: 'js', path: '/react-16.11.0.production.min.js', attributes: { defer: 'defer' }, // defer: load完成后不立即执行,等带页面DOMLoaded事件执行前执行,等价于把script放到所有dom之后 publicPath: assetsPath, append: false, }, { type: 'js', path: '/react-dom-16.11.0.production.min.js', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/react-router-5.2.1.min.js ', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/react-router-dom-5.2.1.min.js', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/axios-0.26.0.min.js', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/moment.min.js', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/lodash-4.17.21.min.js ', attributes: { defer: 'defer' }, publicPath: assetsPath, append: false, }, { type: 'js', path: '/moment-timezone-with-data-10-year-range.min.js', attributes: { defer: 'defer' }, publicPath: assetsPath, append: true, }, ], }), new CopyWebpackPlugin({ patterns: [ { from: 'public', globOptions: { ignore: ['**/index.html'], }, to: 'dist', }, ], }), ].concat(!isDev ? [new BundleAnalyzerPlugin({analyzerPort: 8889, analyzerMode: 'static'})] : []), }
2023年12月14日
73 阅读
0 评论
0 点赞
2023-12-11
记录在TS项目中使用eslint规范代码时遇到的问题
一、代码无法识别 as 表达式报错内容:as语句无法识别,导致(window as any).hello这种语句报错问题原因:eslint 在检测代码时,会先将代码转换为 AST 对象 而这个转换过程需要指定的解析器才能完成,eslint 默认使用的是babel解析器,而babel解析器里没有包含ts语法内容的解析器,所以,我们需要使用ts为eslint开发的解析器解决方法:确保安装了eslint以及ts eslint解析器 npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin修改eslint配置文件 .eslintrc.js 中的解析器的配置项,配置内容如下module.exports = { root: true, env: { browser: true, mocha: true, node: true, es6: true, commonjs: true }, plugins: [ '@typescript-eslint/eslint-plugin', // 加载插件,使其对代码进行处理 'react', 'import' ], parser: '@typescript-eslint/parser', // 指定AST解析器为ts的eslint解析器 // ... 其他配置 }二、在interface或者type类型声明中,函数生命中的参数类型表达式报 'xxx' is defined but never used.eslintno-unused-vars报错内容:在interface或者type类型声明中,函数生命中的参数类型表达式报 'xxx' is defined but never used.eslintno-unused-vars报错原因:eslint在执行 no-unused-vars 规则检测时,使用的是默认的检测规则,也就是 js 的变量检测规则解决方法:禁用默认的no-unused-vars改为 @typescript-eslint/no-unused-vars 这个规则会排除interface或者type类型声明中的无函数体函数的检测,更改后的rules内容rules: { 'react/jsx-filename-extension': [ 'error', { extensions: ['.js', '.jsx', '.ts', '.tsx'] } ], // ... 其他配置 'eol-last': 2, // 文件以单一的换行符结束 // 'no-unused-vars': [1, { vars: 'all', args: 'after-used' }], // 不能有声明后未被使用的变量或参数 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': ['error'], // ... 其他配置 }
2023年12月11日
49 阅读
0 评论
1 点赞
2023-01-12
使用ua-parser库处理userAgent判断微信授权登录支持的浏览器
平时我们在js中判断浏览器名称和版本都是通过解析userAgent字符串来判断,但是自己挨着用字符串判断始终不能保证处理的准确性,这种时候就可以考虑找找社区有没有比较成熟的解析库了,成熟的库优势就是经过比较漫长的迭代沉淀,且根据用户反馈做了更多的优化调整。对于ua解析库,比较成熟的就是 ua-parser 了,ua-parser 有很多语言版本,支持 python php golang 等,前端直接使用 ua-parser-js 就可以了import UAParser from 'ua-parser-js'; const WECHAT_SUPPORT_DEVICE = [ { // 微信内 webview browser: 'wechat', }, { // uc浏览器 browser: 'ucbrowser', }, { // qq 浏览器 browser: 'qqbrowser', }, { // ios safari 浏览器 browser: 'mobile safari', os: 'ios', }, ]; function isWechatSupportDevice(): boolean { const parser = new UAParser(navigator.userAgent); // you need to pass the user-agent for nodejs const parserResults = parser.getBrowser(); const browserName = parserResults.name; console.log(browserName); const isValid = WECHAT_SUPPORT_DEVICE.some((item) => item.browser === browserName.toLowerCase()); return isValid; },
2023年01月12日
283 阅读
0 评论
0 点赞
2022-11-30
前端常用框架或库收集整理
前端常用框架或库收集整理React 常用组件react-use 常用的自定义 hooks 合集react-hook-form 最常用 react 表单处理hooks,用来做表单验证处理,提交等react-cool-img react图片懒加载react-cool-inview react元素块内容进入页面可视区域监听组件,类似于react-dnd 拖放效果组件react-sortable-tree 可以排序的树形组件@uiw/react-md-editor md 编辑器,可以自定义控件,如上传等shepherdjs 网站新手引导框架 也有react 组件 https://shepherdjs.dev/docs/react-files-uploading react 文件上传组件 https://www.npmjs.com/package/react-files-uploadingreact-images-uploading react 图片上传组件 https://www.npmjs.com/package/react-images-uploadingreact-intersection-observer react 图片和dom懒加载 https://github.com/thebuilder/react-intersection-observerreact-share 网站分享快速生成按钮和图表的组件NodeJscheerio 用jquery语法来解读提取html文本内容的爬虫内容分析库ora 命令行loading工具consola 命令行人机交互输入工具,可以异步执行多个输入,单选,多选,确认 操作commander 命令行工具,注册命令,指定命令的说明,可选参数,以及要执行的代码,一般配合上面的 consola 来实现命令行工具UI 组件库ElementUI vue 框架使用最多的组件库Framework7 支持所有主流前端框架,三端都有组件库JS 绘图jsplumb 拓扑图绘制框架fabricjs canvas库,支持画图,绑定操作,事件等,让canvas变简单ECharts 不用多说,无人不知,无人不晓Cytoscape.js 主要用来画连线图,如关系图谱JS 动画Tween.js 一个简单的 JavaScript 补间(比如css3的ease-in)动画库Snap.svg 绘制svg的类库,超级简单方便的apiAnime.js 类似jquery和jquery-ui的动画库,直接操作domwaypoint.js jquery监听dom进入浏览器可是窗口区域插件parallax.js 视距差效果JS工具函数html-to-text 将html内容转换成纯文本去除富文本内容音视频相关webm-muxer/mp4-muxer 音视频录制并生成视频工具库 https://www.npmjs.com/package/webm-muxerjs-audio-recorder https://www.npmjs.com/package/js-audio-recorder 音频录制,支持录制时的声波显示等,非常强大代码编辑器Ace editor Ace是一个用JavaScript编写的嵌入式代码编辑器。它与Sublime,Vim和TextMate等原生编辑器的功能和性能相匹配。它可以很容易地嵌入到任何网页和JavaScript应用程序中。作为与codemirror同类的现代编辑器,ACE同样拥有mode进行语法解析,实现编辑器的智能感知型功能。CodeMirror 是一个用JavaScript为浏览器实现的多功能文本编辑器。它专门用于编辑代码,并附带一些实现更高级编辑功能的语言模式和插件。其核心仅提供编辑器功能,其他功能通过丰富的API和插件实现。CodeMirror的使用基于特定的程序语言模式(mode),它对特定的语言进行语法解析(parse),使编辑器能够在解析结果基础上进行语法高亮,实现具有上下文感知(context-aware)的代码补全、缩进等功能。monaco editor monaco是VS Code的代码编辑器,同时也是一个开源代码编辑器,可以嵌入到Web应用程序中社区整理常用库10个按钮特效 http://www.adobeedu.com/%E8%BF%9910%E4%B8%AA%E6%8C%89%E9%92%AE%EF%BC%8C%E6%8A%8A-css-hover-%E7%9A%84%E5%88%9B%E6%84%8F%E5%8F%91%E6%8C%A5%E5%88%B0%E6%9E%81%E8%87%B4%E4%BA%86/HTML5+CSS3 最酷的 loading 效果收集 https://www.runoob.com/w3cnote/free-html5-css3-loaders-preloaders.html
2022年11月30日
334 阅读
1 评论
0 点赞
2022-11-16
[webpack踩坑路之]css提取插件mini-css-extract-plugin和speed-measure-webpack-plugin冲突
当我们使用webpack5.x打包项目时,在现网环境需要使用mini-css-extract-plugin将我们的样式打包到独立的样式文件中,使用官方推荐配置能正常运行const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // all options are optional filename: "[name].css", chunkFilename: "[id].css", ignoreOrder: false, // Enable to remove warnings about conflicting order }), ], module: { rules: [ { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { // you can specify a publicPath here // by default it uses publicPath in webpackOptions.output publicPath: "../", }, }, "css-loader", ], }, ], }, };但是当我们同时使用了 speed-measure-webpack-plugin 插件来打印各个module的打包时间时,就会出现无法正常打包的情况,报错信息如下:Webpack 5 fails as soon as I smp.wrap() my config, with the following error: ERROR in ..../Error.scss Module build failed (from ../../node_modules/mini-css-extract-plugin/dist/loader.js): Error: You forgot to add 'mini-css-extract-plugin' plugin (i.e. `{ plugins: [new MiniCssExtractPlugin()] }`), please read https://github.com/webpack-contrib/mini-css-extract-plugin#getting-started at Object.pitch (.../node_modules/mini-css-extract-plugin/dist/loader.js:50:14)这时候我们需要去判断下,再不需要输出打包时间的情况下,不使用 smp 插件,如,我的方式const wrapConfig = isDev ? smp.wrap : (config) => config; module.exports = wrapConfig({ })
2022年11月16日
332 阅读
0 评论
0 点赞
2022-11-12
fabricjs马赛克笔刷
最近在做一个浏览器插件,其功能是截取当前网页的部分内容,然后像聊天工具截图那样编辑图片,其中的一个工具的给图片打马赛克。实际效果如下通过方案对比最终采用了自定义画笔的方式来实现而不是矩形区域框选的方案。代码如下:PS: 以下代码基于fabricjs 5.2.1 版本生成马赛克笔刷的工具函数 fabric-brush.tsimport { IMosaicPatternBrush } from '@/types/fabric-shim'; import { fabric } from 'fabric'; const mosaicify = (imageData: ImageData) => { const { data } = imageData; const iLen = imageData.height; const jLen = imageData.width; let index; let i; let j; let r; let g; let b; let a; let _i; let _j; let _iLen; let _jLen; // const { blockSize } = this; const blockSize = 20; for (i = 0; i < iLen; i += blockSize) { for (j = 0; j < jLen; j += blockSize) { index = (i * 4 * jLen) + (j * 4); r = data[index]; g = data[index + 1]; b = data[index + 2]; a = data[index + 3]; _iLen = Math.min(i + blockSize, iLen); _jLen = Math.min(j + blockSize, jLen); for (_i = i; _i < _iLen; _i++) { for (_j = j; _j < _jLen; _j++) { index = (_i * 4 * jLen) + (_j * 4); data[index] = r; data[index + 1] = g; data[index + 2] = b; data[index + 3] = a; /* data[index] = 0; data[index + 1] = 0; data[index + 2] = 0; */ } } } } }; export const mosaicBrush = (fabricCanvas: fabric.Canvas): IMosaicPatternBrush => { const squareBrush: IMosaicPatternBrush = new fabric.PatternBrush(fabricCanvas); // getPatternSrc 取得要重复绘製的图形 Canvas squareBrush.getPatternSrc = function() { // 创立一个暂存 canvas 来绘製要画的图案 const cropping = { left: 0, top: 0, width: fabricCanvas.width, height: fabricCanvas.height, }; const imageCanvas = fabricCanvas.toCanvasElement(1, cropping); const imageCtx: any = imageCanvas.getContext('2d'); const imageData = imageCtx.getImageData(0, 0, imageCanvas.width, imageCanvas.height); mosaicify(imageData); imageCtx.putImageData(imageData, 0, 0); const patternCanvas = (fabric as any).document.createElement('canvas'); // 这里的ceateElement一定要使用fabric内置的方法 const patternCtx: any = patternCanvas.getContext('2d'); patternCanvas.width = fabricCanvas.width || 0; patternCanvas.height = fabricCanvas.height || 0; patternCtx.drawImage( imageCanvas, 0, 0, imageCanvas.width, imageCanvas.height, cropping.left, cropping.top, cropping.width, cropping.height ); return patternCanvas; }; return squareBrush; }; 使用// 生成马赛克画笔实例 const brush: IMosaicPatternBrush = mosaicBrush(fabIns); // 这里不能少,否则画出来的内容不会生效,会被其他内容覆盖 brush.source = brush.getPatternSrc.call(brush); // 设置画笔 fabIns.freeDrawingBrush = brush;
2022年11月12日
381 阅读
0 评论
0 点赞
2022-06-26
使用webpack打包对外lib时import取到的是空对象或undefined
首先,webpack默认认为你现在正在开发的是一个应用而不是一个对外使用的库,所以默认打包结构是一个闭包,然后模块是作为闭包的参数列表,是个数组,每一项也是个匿名函数也就是说,你在代码中 export 暴露出的对象,都在闭包中,所以也就不会对外暴露对象。解决方案:修改webpack配置文件,在 output 配置中加入如下配置library: 'libName', // libName 为对外暴露的库名称 libraryTarget: 'umd' // 定义模块运行的方式,将它的值设为umd参考官方文档:Output | webpack我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=24299ll4gdokg
2022年06月26日
388 阅读
0 评论
0 点赞
2022-02-27
express框架下获取用户真实ip地址
1、配置nginx在http,或者 server 或者 location 中加入如下配置proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;2、nodejs 获取方法var ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
2022年02月27日
343 阅读
0 评论
0 点赞
2021-04-18
jsplumb 开发文档收集
jsplumb基本概念https://www.jianshu.com/p/0e7bb5c081c8https://www.jianshu.com/p/0e7bb5c081c8jsplumb 阅读笔记(英文文档翻译)https://www.cnblogs.com/ysx215/p/7615677.html拓扑图编辑器-jsplumb基本配置https://www.jianshu.com/p/d68a8e61ff2d【原英文文档】https://docs.jsplumbtoolkit.com/community/current/articles/connections.html#detachinggithub 中文文档https://github.com/MarvenGong/jsplumb-chinese-tutorial
2021年04月18日
217 阅读
0 评论
0 点赞
2020-12-23
gitbook出现TypeError: cb.apply is not a function解决办法
执行gitbook serve的时候出现如下错误> fastmock-doc@1.0.0 serve /Users/gongminghua/Public/03private/fastmock-docs > gitbook serve Live reload server started on port: 35729 Press CTRL+C to quit ... /usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287 if (cb) cb.apply(this, arguments) ^ TypeError: cb.apply is not a function at /usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287:18 at FSReqCallback.oncomplete (fs.js:169:5) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! fastmock-doc@1.0.0 serve: `gitbook serve` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the fastmock-doc@1.0.0 serve script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /Users/gongminghua/.npm/_logs/2020-12-23T02_00_45_660Z-debug.log 按照提示中的路径,/usr/local/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js 打开polyfills.js文件,找到这个函数function statFix (orig) { if (!orig) return orig // Older versions of Node erroneously returned signed integers for // uid + gid. return function (target, cb) { return orig.call(fs, target, function (er, stats) { if (!stats) return cb.apply(this, arguments) if (stats.uid < 0) stats.uid += 0x100000000 if (stats.gid < 0) stats.gid += 0x100000000 if (cb) cb.apply(this, arguments) }) } }在第62-64行调用了这个函数fs.stat = statFix(fs.stat) fs.fstat = statFix(fs.fstat) fs.lstat = statFix(fs.lstat)把这三行代码注释掉就解决报错了
2020年12月23日
363 阅读
0 评论
0 点赞
1
2
3