万字总结webpack实战案例配置

封面

一文了解webpack中常见实战案例配置

  • 🛴序言
  • 🚌一、Library的打包
    • 1. webpack打包库
    • 2. 库引用冲突
  • 🚍二、PWA的打包配置
    • 1. PWA是什么
    • 2. webpack中的PWA
  • 🚎三、TypeScript的打包配置
    • 1. 引例阐述
    • 2. webpack对ts的配置
      • (1)背景
      • (2)配置步骤
    • 3. ts识别第三方库
  • 🚕四、WebpackDevServer进阶操作
    • 1. WebpackDevServer实现请求转发
    • 2. WebpackDevServer解决单页面应用路由问题
  • 🚖五、ESLint在Webpack中的配置
    • 1. ESLint是什么
    • 2. 如何安装ESLint
    • 3. 为什么要在webpack中配置ESLint
  • 🏎️六、Webpack性能优化
    • 1. 跟上技术的迭代(Node,Npm,Yarn)
    • 2. 在尽可能少的模块上应用Loader
    • 3. 合理使用插件
    • 4. resolve参数合理配置
      • (1)常见配置
      • (2)参数讲解
    • 5. 使用DllPlugin提高打包速度
    • 6. 控制包文件大小
    • 7. 多进程打包
    • 8. 合理使用sourceMap
    • 9. 结合 stats 分析打包结果
    • 10. 开发环境内存编译
    • 11. 开发环境无用插件剔除
  • 🏍️七、多页面打包配置
  • 🛵八、结束语
  • 🐣彩蛋 One More Thing
    • (:往期推荐
    • (:番外篇

🛴序言

在前面的两篇文章中,我们讲解了 webpack 的入门知识。但是呢,入门知识了解了之后,总得应用到具体的案例当中来。

因此,在下面的这篇文章中,将带领大家来了解关于 webpack 的一些实战案例配置,包括第三方库、 PWAts 的打包配置,以及 WebpackDevServer 的进阶操作,还有需重点掌握的,关于 webpack 如何做性能优化处理这个问题。

下面开始本文的介绍~🚦

🚌一、Library的打包

假设我们现在要开发一个组件库或者一个函数库时,对于这样的库代码,我们应该如何让 webpack 来进行打包呢?

1. webpack打包库

假如我们现在写了很多逻辑代码,同时呢,我们将这些逻辑代码进行打包,打包之后它全部生成在 dist 文件夹下的 mondaylib.js 文件中。

好了,现在这个库生成了。那如何让我们的用户,来引入 mondaylib 这个库呢?

一般情况下,别人引入我们的库的方法,具体有以下几种方式:

//方式一
import mondaylib from 'mondaylib'
//方式二
const mondaylib = require('mondaylib')
//方式三
require(['mondaylib'], function(){})

所以,如果想让我们的用户来引入这个库,我们需要在 webpack.config.js 下进行配置。具体配置如下:

const path = require('path');module.exports = {mode: 'production',entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'mondaylib.js',//此处配置libraryTarget,umd表示支持commonJS这种语法libraryTarget: 'umd'}
}

libraryTarget: 'umd' 表示支持 commonJS 这种语法,因此可以引入上面三种方式。同时, libraryTarget 也可以设置为其他值,比如 thiswindow

libraryTarget: 'this' 的意思为,我要让 mondaylib 这个变量,挂载到页面上。 libraryTarget: 'window' 则表示为, mondaylib 这个变量,将挂载到 window 上。


除了以上三种情况,还有另外特殊情况,具体如下:

<script src="mondaylib.js"></script>

此时我们需要在 webpack.config.js 中进行以下配置:

const path = require('path');module.exports = {mode: 'production',entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'mondaylib.js',//将打包生成的代码挂载到页面的全局变量上library: 'mondaylib',//此处配置libraryTarget,umd表示支持commonJS这种语法libraryTarget: 'umd'}
}

其中,第一个 library 是属性值,第二个 mondaylib 是我们的库名,这个配置的意思为,将打包生成的代码,即 mondaylib.js 这个库,给挂载到全局的变量上。

2. 库引用冲突

假设现在,我们在上面 mondaylib 这个库中,引入了 lodash 这个库。然后呢,当用户使用的时候,用户又再引入了一次lodash这个库。像下面代码这样:

import _ from 'lodash';
//mondaylib这个库原先已经引入过lodash这个库
import mondaylib from 'mondaylib';

所以现在,我们该如何来避免这种问题发生呢?我们再 webpack.config.js 中进行配置,具体代码如下:

const path = require('path');module.exports = {externals: ["lodash"]
}

从以上代码中我们可以知道,通过 externals: ["lodash"] 这个配置,来告诉 webpack ,告诉它说,如果在打包过程中, mondaylib 这个库中如果有遇到 lodash 这个库,那么就避开它,不要进行打包。通过这种方式,可以有效地避免库多次引用的问题,减少代码的打包大小。


externals 还有另外一种特殊配置,如下代码所示:

module.exports = {externals: {// 表明lodash这个库如果在commonjs这种环境下被使用,那么要求lodash加载的时候必须叫做lodashlodash: {commonjs: 'lodash'}}
}

如果这样配置,意在表明 lodash 这个库如果在 commonjs 这种环境下被使用,那么要求 lodash 加载的时候,必须命名为 lodash ,而不能随意命名。像下面这样:

//✔可使用方式:命名为lodash
import lodash from 'lodash'
//✘不可使用方式:未命名为lodash
import _ from 'lodash'

🚍二、PWA的打包配置

1. PWA是什么

PWA,全称为 Progressive Web Application ,即渐进式Web应用程序。

PWA 是一门比较新的前端技术,那它是一种什么样的技术呢?

PWA 可以实现的效果是,如果你访问一个网站,有可能第一次你访问成功了,但是呢,突然间这个网站的服务器挂掉了。那么这个时候你访问网站应该就是没办法访问了。但是呢, PWA 会将你第一次访问的页面给缓存起来。之后即使服务器挂掉了,你依然可以把之前看到的页面再展示出来。

因此, webpack 中有一个插件,可以来实现这样的效果。我们来了解一下~

2. webpack中的PWA

第一步: 安装插件。具体代码如下:

npm install workbox-webpack-plugin --save-dev

第二步:webpack.prod.js 中引入该插件并使用。具体代码如下:

const WorkboxPlugin = require('workbox-webpack-plugin');module.exports = {plugins: [new WorkboxPlugin.GenerateSW({clientsClaim: true,skipWaiting: true})],
}

通常情况下,我们只需要在线上环境 prod 引入 PWA ,而在开发环境中不需要考虑这个问题。通过以上的配置,我们在项目打包完成之后, dist 目录下将生成两个新的文件,一个是 service-worker.js ,另外一个是 precache.js 文件,这两个文件就是供我们来使用 PWA 的。


第三步: 引入以上文件。具体代码如下:

if('serviceWorker' in navigator){window.addEventListener('load', () => {navigator.serviceWorker.register('/service-worker.js').then(registration => {console.log('service-worker registed');}).catch(error => {console.log('service-worker regist error');})})
}

我们需要在入口文件中,写一段业务代码,引入 service-worker.js 文件,来帮我们做 PWA 。这个时候我们对项目进行打包,之后呢,如果出现服务器突然挂了的情况,那也不用担心, PWA 会帮我们加载原先的页面来提供给我们浏览。

🚎三、TypeScript的打包配置

1. 引例阐述

我们都知道,对于不同的开发者来说,不同的人写出的代码风格形式各异,这样在后期,项目的维护性就很难得到保证。那么,这个时候,风靡于2018年的 Typescript 出现了。 ts 规范了一套 js 的标准,因此,我们在项目代码的编写中,通过 ts ,就可以规范我们的代码,并且使得我们项目的维可维护性和可扩展性变得更好了。

接下来,我们就来了解一下,如何通过 webpack 的配置变更,来实现对 ts 语法的支持。

2. webpack对ts的配置

(1)背景

假设我们现在有这么一段 ts 的代码需要进行编译,具体代码如下:

class Greeter{greeting: string;constructor(message: string){this.greeting = message;}greet(){return "Hello, " + this.greeting;}
}let greeter = new Greeter("world");let button = document.createElement('button');
button.textContent = "Say Hello";
button.click = function(){alert(greeter.greet());
}document.body.appendChild(button);

现在,我们想要让 webpack 来对这段 ts 代码进行编译,该怎么处理呢?

(2)配置步骤

第一步: 安装 ts-loader具体命令如下:

npm install ts-loader typescript -D

第二步: 我们在 webpack.config.js 文件下进行配置。具体代码如下:

const path = require('path');module.exports = {mode: 'production',entry: './src/index.tsx',module: {rules: [{test: /\.tsx?$/,use: 'ts-loader',exclude: /node_modules/ }]},output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')}
}

第三步: 配置 tsconfig.json 文件。具体代码如下:

{"compilerOptions": {"outDir": "./dist","module": "es6","target": "es5","allowJs": true}
}

3. ts识别第三方库

有时候,我们会调用 lodash 中的 join 方法,但是呢,如果我们不进行特殊处理的话,在 tsx 文件中正常引入 lodash 这个库并使用,是不会报错的。因此,我们需要来安装另外一个 ts 的库,来对它进行处理一下。具体步骤如下:

第一步: 安装 @types/lodash 库。具体命令如下:

npm install @types/lodash --save-dev

安装完这个库之后, ts 就可以去识别 lodash 的一些函数和方法,一旦出现引用不对,就会进行报错提示。

那有小伙伴就会有疑问说,是不是 ts 拥有所有这样的库(像 jQuery 等各种库)的类型文件呢?

答案当然是否定的。我们可以到 github 上的一个网址👉https://microsoft.github.io/TypeSearch/来进行搜索,如果搜索得到,那么我们就可以用 @type/库名 来进行安装,之后 tsx 文件就会支持对该库的类型检查。

🚕四、WebpackDevServer进阶操作

1. WebpackDevServer实现请求转发

一般情况下,我们可以通过 charles fiddler 工具,在本地搭建一个代理服务器。通过这台代理服务器,将我们想要请求的接口地址进行转发。

那在 webpack 中,给我们提供了一个工具, devServer.Proxy 。接下来,我们在 webpack.config.js 中进行配置,具体代码如下:

module.exports = {devServer: {proxy: {'/react/api': {target: 'http://www.mondaylab.com',//实现对https网址的请求转发secure: false,bypass: function(req, res, proxyOptions){//如果请求的内容是一个html地址,那么就直接返回根路径下index.html的内容if(req.headers.accept.indexOf('html') !== -1){console.log('Skipping proxy for browser request');return './index.html';// return false; //表示如果遇到html请求,那么该给你返回什么就返回什么}},//在前端请求时写header.json,webpack会间接的帮我们拿到demo.json的数据(请求转发】)pathRewrite: {'header.json': 'demo.json'},//如果有一些网站做了防爬虫,那么我们可能没办法进行跨域。需要进行如下配置,就可以突破对origin的限制changeOrigin: true,// 在请求头中自定义一些内容headers: {host: 'www.mondaylab.com',//在做请求转发时模拟一些登录等操作cookie: 'gfhgfh'}}}}
}

2. WebpackDevServer解决单页面应用路由问题

对于现代的的主流框架来说,像 vue.jsReact.js 等等框架,基本都是单页面应用。那么,在单页面应用里,比如我们想要从 http://mondaylab.com 跳转到 http://mondaylab.com/list ,该怎么样进行跳转呢?

这就要谈到一个单页面应用的路由问题。我们需要在 webpack.config.js 中进行如下配置:

module.exports = {devServer: {//第一种方式historyApiFallback: true,/*等同于historyApiFallback: {rewrites: [{from: /\.*\/,to: '/list.html/'}]}*//*第二种方式historyApiFallback: {rewrites: [{from: /abc.html/,//进行转换,当访问abc.html时,会把list.html的内容展示出来to: '/list.html/'}]}*//*第三种方式:更为灵活historyApiFallback: {rewrites: [{//表明在做页面的替换时,通过一个函数function的形式,结合context的一些参数//做一些js的逻辑放在里面,来决定最终它跳转到哪from: /^\/(libs)\/.*$/,to: function(context){return '/bower_components' + context.match[0];}}]}*/}
}

值得注意的是, historyApiFallback 只能用于开发环境下。如果到了线上环境的话,需要让后端的小伙伴去 nginx 或者 apache 上,仿照 webpackDevServer 的一些配置,在后端的服务器上做同样的配置,配置之后前端才可以使用对应的路由。

🚖五、ESLint在Webpack中的配置

1. ESLint是什么

在我们日常的团队开发中,每个人写的代码都各式各样,比如有的人喜欢在代码后边加个分号,有的人又不喜欢加。这间接地,就很容易导致我们项目的可维护性变差了。因此呢,我们就引入了 ESLint 这个内容,来约束的代码规范,让项目的可维护性和可扩展性变高。

ESLintWebpack 中是怎么样配置的呢?

2. 如何安装ESLint

第一步: 安装 ESLint 工具。具体命令如下:

npm install eslint --save-dev

第二步: 约束我们的代码。我们需要新建一个配置文件,来对我们的ESLint规范进行配置。具体命令如下:

npx eslint --init
> Use a popular style guide 使用通用的代码检测模板
> Airbnb
> Do you use React 根据自身需求填y或者n
> Javascript
> Would you like to install them now with npm? Y

第三步: 使用 eslint 检测代码规范。具体代码如下:

npx eslint src

以上代码表示的是,使用eslint来检测src目录下的代码规范。

3. 为什么要在webpack中配置ESLint

在上面中我们了解到,每个开发的小伙伴都可以用命令行来检测自己的代码规范,但是如果每回写完一次代码,我们都要去运行这样的命令,才能看我们的代码写的合不合理,这样会不会就有点麻烦了。同时,我们又也不能保证每个人的 eslint 的代码规范设置是不是一样的。

因此,我们可以在 webpack 中来进行配置,解决上述所说的问题。具体步骤如下:

第一步: 安装 eslint-loader具体命令行如下:

npm install eslint-loader --save-dev

第二步: 配置 webpack.config.js具体代码如下:

module.exports = {devServer: {/*当我们运行webpack做打包时,一旦代码出现规范问题,webpack将会在浏览器上弹出一个报错层来提示我们*/overlay: true  },module: {rules: [{ test: /\.js$/, exclude: /node_modules/, use: ['babel-loader', 'eslint-loader']}]}
}

了解完基础配置之后,接下来我们来了解一些 eslint-loader 的一些其他配置。具体代码如下:

module.exports = {module: {rules: [{ test: /\.js$/, exclude: /node_modules/, use: ['babel-loader', {loader: 'eslint-loader',options: {//如果代码有一些比较浅显的问题,eslint-loader将会帮助我们自动修复fix: true,//降低eslint在打包过程中对项目性能的损耗cache: true},//强制eslint-loader先执行fore: 'pre'}]}]}
}

🏎️六、Webpack性能优化

细心的小伙伴可能已经发现,webpack的打包速度有时候可能会有一点点慢。这间接地,会浪费我们很多不该浪费的时间。所以,接下来就来谈谈,提升 Webpack 打包速度的几种方法。

1. 跟上技术的迭代(Node,Npm,Yarn)

如果我们想提升 webpack 的打包速度,我们可以升级 webpack 的版本,或者升级我们的node、npm管理器或者yarn的版本。

那为什么升级这些工具可以提升 webpack 的打包速度呢。

大家想一下, webpack 在做每一个版本的更新时,内部肯定会做很多版本的优化,因此,当我们做 webpack 的版本更新时,在速度上肯定会有所提升。 nodenpmyarn 的更新也是同样的道理。

试想一下,如果不提升,那它升级的意义又在哪呢?对吧。

2. 在尽可能少的模块上应用Loader

一般情况下,第三方模块的库都是已经进行打包编译过的,所以我们需要在引入 loader 来进行编译时,对 node_module 的文件给忽略掉,或者只在某个文件夹下使用某个 loader ,以此来增加我们的打包速度。我们可以在 webpack.config.js 中进行配置,具体代码如下:

module.exports = {module: {rules: [{ test: /\.js$/, exclude: /node_modules/,//或者以下这种方式->include//include: path.resolve(__dirname, '../src'),use: [{loader: 'babel-loader'}]}]}
}

当然,依据上面这个思路,还有其他的 loader 也都有其相对应的注意事项,这里不再展开细述。

3. 合理使用插件

插件要合理的使用,不要使用那些冗余的,没有意义的插件。同时呢,也要选择那些,性能比较好的,官方认可的插件来使用,这样,可以有效的来提升 webpack 的打包速度。

4. resolve参数合理配置

(1)常见配置

有时候,我们想要对我们引入的文件进行一些自定义的配置,该怎么处理呢?具体配置如下:

module.exports = {resolve: {extensions: ['js', 'jsx'],/*** 1.当你只引入一个目录时,比如 import Child from './child/child' ,* 这个时候webpack不知道我们具体是要引入哪个文件,* 那么会先去找index文件,如果找不到,那它会继续去找child文件*/mainFiles: ['index', 'child'],/*** alias, 顾名思义是别名。* 比如,想要将某个文件的引入方式改为自己的名字* import Child from './Child' -> import Child from 'monday'*/alias: {monday: path.resolve(__dirname, '../src/Child'),}},
}

接下来对以上的几个参数进行详细讲解。

(2)参数讲解

1)extensions

  • 比如当引入 import Child from './child/child' 时,会先去找 './child/child.js' 文件,找不到再去找 './child/child.jsx' 文件。
  • 一般不配置css和图片文件,因为css和图片可能数量会比较多,相应的会去执行很多次查找。间接地,本来想提升性能,结果又变成了浪费性能了。
  • 所以,如果是像 cssjpg 等之类的资源文件,应该进行显式的引入;如果是像 jsjsx 之类的逻辑文件,可以在 extesions 中配置,进行显式的引入。

2)mainFiles

当你只引入一个目录时,比如 import Child from './child/child' ,这个时候 webpack 不知道我们具体是要引入哪个文件,那么会先去找 index 文件,如果找不到,那它会继续去找 child 文件。

3)alias

  • alias , 顾名思义是别名。比如,想要将某个文件的引入方式改为自己的名字 import Child from './Child' -> import Child from 'monday'
  • 常用于多层级目录的情况下。

5. 使用DllPlugin提高打包速度

有时候,我们希望引入的第三方模块,只在第一次做打包的时候进行分析,而后续再做打包时就不要再进行分析了。那该怎么处理呢?

第一步: 新建 webpack.dll.js 文件,并进行配置。具体代码如下:

const path = require('path');
const webpack = require('webpack');module.exports = {mode: 'production',entry: {//此处填写我们想要单独进行打包的第三方库名vendors: ['react', 'react-dom', 'lodash']},output: {filename: '[name].dll.js',path: path.resolve(__dirname, '../dll'),/*用library把第三方模块里面的所有代码,通过全局变量的方式暴露出去*/library: '[name]'},plugins: [/*暴露完成之后,借助DllPlugin插件对暴露出来的模块代码进行分析,最终生成manifest.json的文件 */new webpack.DllPlugin({//对生成的vendors的库进行DllPlugin的分析(文件映射)name: '[name]',// 分析结果所放的路径,分析之后结合全局变量,在common.js中进行配置path: path.resolve(__dirname, '../dll/[name].manifest.json')})]}

第二步: 安装 add-asset-html-webpack-plugin 插件。具体命令如下:

npm install add-asset-html-webpack-plugin --save

第三步: 配置 webpack.common.js 文件。具体配置如下:

const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
const webpack = require('webpack');module.exports = {entry: {main: './src/index.js',plugins: [new HtmlWebpackPlugin({template: 'src/index.html'}), /*** 指的是要往HtmlWebpackPlugin插件生成的index.html中添加一些内容*/new AddAssetHtmlWebpackPlugin({filepath: path.resolve(__dirname, '../dll/vendors.dll.js')}),/*** 1.使用DllReferencePlugin插件,* 这个插件会到'../dll/vendors.manifest.json'中找第三方模块的映射关系,* 如果能找到映射关系,那么webpack就会知道,这个第三方模块没有必要再打包进来了,* 直接从vendors.dll.js中拿过来用就可以了* 2.如果发现并不再映射关系里面,那么才会再到node_modules中去找* */new webpack.DllReferencePlugin({manifest: path.resolve(__dirname, '../dll/vendors.manifest.json')})]}
}

第四步: 配置 package.json 文件。具体代码如下:

{"scripts": {"build:dll": "webpack --config ./build/webpack.dll.js"}
}

通过运行 npm run build:dll 命令,来实现对第三方库的打包。

6. 控制包文件大小

在我们做项目打包时,我们应该让我们打包生成的文件尽可能的小。有时我们在写代码的时候,经常会在页面里面引入一些没有用的模块,也就是引入一些我们使用的模块。

这个时候如果你没有配置 Tree-Shaking ,就会很容易造成打包的时候,出现大量冗余的代码。这些冗余代码呢,间接地,就会拖累我们 webpack 的打包速度。

所以呢,我们在做打包时,要控制好文件的大小。具体步骤参考如下:

  • 配置 Tree-shaking
  • 通过 SplittingChunk 来将一个大的文件分割成多个小的文件。

7. 多进程打包

webpack 是通过node来运行的,所以它的打包过程是单线程的。那有时候呢,我们也可以借助 node 里面的多进程,来帮助我们提升 webpack 的打包速度。

常见工具有 thread-loaderparallel-webpackhappypack 等工具,大家可以依据自身需求查找相关资料,选出最适合自己项目的工具,进行打包。这一块不再进行详细讲解~

8. 合理使用sourceMap

通常情况下, sourceMap 越详细,那么打包的速度就会越慢。所以在做打包的时候,要根据当前是开发环境还是生产环境,选出最合适的 sourceMap 配置,来生成我们对应的代码调错文件。

这样,一方面能保证我们即使发现代码里的错误问题。另一方面呢,也可以尽可能地提升打包速度。

9. 结合 stats 分析打包结果

在打包项目时,我们可以通过命令,来生成这次打包情况的 stats 文件,之后呢,通过借助一些线上或者本地的打包分析工具,来达到分析我们本次打包过程中的打包情况。

比如说,分析哪个模块打包的时间比较长,哪个模块打包分析的时间比较短等等内容,依据具体的情况进行优化。

10. 开发环境内存编译

使用 webpackDevServer 来进行编译,它不会把打包生成的文件放在 dist 目录中去,而是把其放到了我们电脑的内存中。

11. 开发环境无用插件剔除

比如说,我们在开发环境的情况下,并不需要对代码进行压缩。因此,对应的压缩插件我们就不要在开发环境中配置,只在生产环境中配置就好了。这样,可以减少一些不必要的打包时间。

🏍️七、多页面打包配置

通常情况来说,但凡我们在做打包的时候,基本上都是对单页面应用做打包。什么是单页面呢,也就是只有一个 index.html 文件。像目前比较主流的框架, vuereact 等框架,都是单页面应用。但是如果像一些比较老的框架,比如 jqueryzepto ,可能就需要进行多页面应用打包。

因此,顺着这个话题,我们来谈谈,在 webpack 中,如何对多页面应用,进行打包配置。

我们在 webpack.common.js 中进行配置,具体代码如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {entry: {//引入多个入口文件main: './src/index.js',list: './src/list.js'},plugins: [new HtmlWebpackPlugin({template: 'src/index.html',filename: 'index.html',//chunk表明这些html文件要引入的文件有哪些chunks: ['runtime', 'vendors', 'main']}),new HtmlWebpackPlugin({template: 'src/index.html',filename: 'list.html',chunks: ['runtime', 'vendors', 'list']})]
}

通过以上代码我们可以知道,增加 entryplugins 的配置,来增加多个入口页面,从而达到了多页面应用配置的效果。

🛵八、结束语

通过上文的讲解,相信大家对 webpack 在一些场景中的实战配置有了一定的了解。上面讲述的也是比较浅显的内容,大家可以根据相对应的知识点,进行知识面的拓宽,以便更好的应用到实际的项目当中。

到这里,关于 webpack 的实战案例配置就讲解结束啦!希望对大家有帮助~

如文章有误或有不理解的地方,欢迎小伙伴们评论区留言哦💬

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣彩蛋 One More Thing

(:往期推荐

  • webpack入门基础知识👉不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
  • webpack入门进阶知识👉webpack入门核心知识还看不过瘾?速来围观进阶知识

(:番外篇

  • 关注公众号星期一研究室,第一时间关注优质文章,更多精选专栏待你解锁~
  • 如果这篇文章对你有用,记得留个脚印jio再走哦~
  • 以上就是本文的全部内容!我们下期见!👋👋👋

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员过关斩将--应对高并发系统有没有通用的解决方案呢?

“灵魂拷问&#xff1a;应对高并发系统有没有一些通用的解决方案呢&#xff1f;这些方案解决了什么问题呢&#xff1f;这些方案有那些优势和劣势呢&#xff1f;对性能孜孜不倦的追求是互联网技术不断发展的根本驱动力&#xff0c;从最初的大型机到现在的微型机&#xff0c;在本…

org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the

一:报错 org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement com.wyj.Dao.Bill.BillMapper.getBill. Its likely that neither a Result Type nor a Result Map was specified.二:解决 未在mapper.xml…

.NET5.0 单文件发布打包操作深度剖析

.NET5.0 单文件发布打包操作深度剖析前言随着 .NET5.0 Preview 8 的发布&#xff0c;许多新功能正在被社区成员一一探索&#xff1b;这其中就包含了“单文件发布”这个炫酷的功能&#xff0c;实际上&#xff0c;这也是社区一直以来的呼声&#xff0c;从 WinForm 的 msi 开始&am…

webpack实战之手写一个loader和plugin

webpack实战之编写一个简易的loader和plugin&#x1f514;序言&#x1f3b5;一、如何编写一个Loader1. 碎碎念2. 项目结构3. 业务代码编写&#xff08;1&#xff09;入口文件代码&#xff08;2&#xff09;编写loader&#xff08;3&#xff09;引用loader&#xff08;4&#xf…

手写一个简易bundler打包工具带你了解Webpack原理

用原生js手写一个简易的打包工具bundler&#x1f95d;序言&#x1f349;一、模块分析(入口文件代码分析)1. 项目结构2. 安装第三方依赖3. 业务代码4. 开始打包&#x1f951;二、依赖图谱Dependencies Graph1. 结果分析2. 分析所有模块的依赖关系&#x1f350;三、生成代码1. 逻…

不喜欢 merge 分叉,那就用 rebase 吧

阅读本文大概需要 3 分钟。有些人不喜欢 merge&#xff0c;因为在 merge 之后&#xff0c;commit 历史就会出现分叉&#xff0c;这种分叉再汇合的结构会让有些人觉得混乱而难以管理。如果你不希望 commit 历史出现分叉&#xff0c;可以用 rebase 来代替 merge。rebase &#xf…

你可能对position和z-index有一些误解

一文详解css中的position和z-index&#x1f9c3;序言&#x1f377;一、文章结构抢先知&#x1f378;二、position1. position的取值2. 标准文档流3. 各取值解析&#xff08;1&#xff09;static&#xff08;2&#xff09;relative&#xff08;3&#xff09;absolute&#xff08…

数据结构与算法专题——第九题 外排序

说到排序&#xff0c;大家第一反应基本上是内排序&#xff0c;是的&#xff0c;算法嘛&#xff0c;玩的就是内存&#xff0c;然而内存是有限制的&#xff0c;总有装不下的那一天&#xff0c;此时就可以来玩玩外排序&#xff0c;当然在我看来&#xff0c;外排序考验的是一个程序…

谁动了我的选择器?深入理解CSS选择器优先级

深入理解CSS选择器优先级&#x1f60f;序言&#x1f9d0;文章内容抢先看&#x1f910;一、基础知识1、为什么CSS选择器很强2、CSS选择器的一些基本概念&#xff08;1&#xff09;4种基本概念Ⅰ. 选择器Ⅱ. 选择符Ⅲ. 伪类Ⅳ. 伪元素&#xff08;2&#xff09;CSS选择器的命名空…

leetcode239. 滑动窗口最大值(思路+详解)

一&#xff1a;题目 二:思路 1.这个题不能用优先队列&#xff0c;虽然我们可以通过优先队列得到最大值&#xff0c;但是我们在移动 窗口的时候,便不可以正常的删除元素了 2.虽然不能用优先对列&#xff0c;但是我们依然希望可以得到队首的元素的时候是最大值&#xff0c;同时还…

《ASP.NET Core 与 RESTful API 开发实战》-- (第10章)-- 读书笔记

第 10 章 部署10.1 部署到 IISASP.NET Core 应用程序支持部署到 IIS 中&#xff0c;之后它将作为应用程序的反向代理服务器和负载均衡器&#xff0c;向应用程序中转传入的 HTTP 请求默认情况下&#xff0c;ASP.NET Core 项目的 Program 类使用如下方式创建 WebHostpublic stati…

翠香猕猴桃 和 薄皮核桃,快来下单

猴桃品种有很多&#xff0c;但不是所有的果子都叫翠香。椭圆形&#xff0c;果喙端较尖&#xff0c;黄褐色硬短茸毛&#xff1b;果肉翠绿色&#xff0c;质细多汁&#xff0c;香甜爽口&#xff0c;有芳香味&#xff0c;白色果心。这就是“翠香”&#xff0c;是集酸甜香于一身的猕…

你可能没有听说过 js中的 DOM操作还有这个: HTMLCollection 和 NodeList

一文了解DOM操作中的HTMLCollection和NodeList⛱️序言&#x1f388;一、基础知识1. 定义&#xff08;1&#xff09;HTMLCollection&#xff08;2&#xff09;NodeList2. 属性和方法&#xff08;1&#xff09;HTMLCollection&#xff08;2&#xff09;NodeList&#x1fa81;二、…

leetcode144. 二叉树的前序遍历(递归+迭代)

一:题目 二&#xff1a;上码 1&#xff1a;递归 class Solution { public:void preorder(TreeNode* root,vector<int>&v ) {if(root NULL) return;v.push_back(root->val);preorder(root->left,v);preorder(root->right,v);}vector<int> preorderT…

都说性能调优难?玩转这3款工具,让你秒变“老司机”!

鲁迅说过&#xff1a;菜鸟写业务&#xff0c;老鸟搭架构&#xff0c;高手玩调优。性能调优可谓是食物链顶端的技术&#xff0c;高薪面试必备良品。然而有不少的开发者&#xff0c;工作多年&#xff0c;却对性能调优几乎一无所知&#xff0c;今天就带大家掰扯掰扯&#xff0c;从…

一文梳理JavaScript中常见的七大继承方案

阐述JavaScript中常见的七大继承方案&#x1f4d6;序言&#x1f4d4;文章内容抢先看&#x1f4dd;一、基础知识预备1. 继承的定义2. 继承的方式&#x1f4da;二、6大常见继承方式1. 原型链继承 &#x1f4a1;&#xff08;1&#xff09;构造函数、原型和实例的关系&#xff08;2…

微软发布 Microsoft Edge 85 稳定版

喜欢就关注我们吧&#xff01;微软推出了 Microsoft Edge 85 稳定版&#xff08;85.0.564.41&#xff09;&#xff0c;现在正逐步向用户推送。此版本带来了以下新特性&#xff1a;收藏夹和设置的本地同步。现在可以在自己的环境中的 Active Directory 配置文件之间同步浏览器收…

leetcode94. 二叉树的中序遍历(左中右)

二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

浅谈前端路由原理hash和history

浅谈前端路由原理hash和history&#x1f3b9;序言&#x1f3b8;一、前端路由原理1、SPA2、什么时候需要路由&#x1f3b7;二、Hash模式1、定义2、网页url组成部分&#xff08;1&#xff09;了解几个url的属性&#xff08;2&#xff09;演示3、hash的特点&#x1f3ba;三、Histo…

leetcode145. 二叉树的后序遍历

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*…