1:浏览器兼容性问题产生的原因
浏览器之所以有兼容性问题,是因为,在浏览器发展的历史过程中,有很多不同的浏览器,他们各自有各自的支持的node版本,css 样式,比如a 浏览器支持css2,而b浏览器支持css3,再或者a浏览器 厂商自己搞出来了一个 只能自己浏览器使用的css属性,这个属性,其他浏览器肯定是不能用的. 再有一个原因,即使是同一个浏览器,也有不同的版本,a浏览器 的10.0版本支持的新特性,在a浏览器的 2.0的版本 一定是不可能支持的,因为迭代版本一般都是向上兼容的,同样的,2.0版本的一些属性也许因为某些原因,会在10.0 的版本中删除掉.
总之一言代之,因为各种各样的历史原因,导致了浏览器兼容性问题的出现,如果我们的开发的web应用 只允许在一个浏览器的某个版本使用的话,那是完全不存在兼容性问题的,否则,我们就要处理浏览器的兼容性问题.
2:浏览器兼容性问题有哪些?
网站开发涉及的所有技术,框架,归根究底,最终都会回归到html + css + js 上面,所以个人认为,解决了html,css,js 的兼容性问题,就解决了浏览器的兼容性问题.
从这三个方面出发,答案呼之而出,html 的兼容性问题几乎没有,那剩下的就只有css 和js 的兼容性问题了.
css 兼容性问题产生的原因
1.大家都知道css 是有一个专门的机构负责维护规范的,但是由于历史原因,这个规范在设计之前就已经存在了一些问题,规范也没有办法,就留存了这些问题,比如盒子的概念的这个问题,当然随着ie浏览器的退出,这个问题已经不是问题,但显然这也是产生css 兼容性问题的原因.
2.虽然有机构维护规范,但各大浏览器厂商不一定对规范的设计都进行了实现,你规范你的,我不遵守,你来打我呀,这是第二个原因.
3.规范的形成是需要很长时间的沉淀的,即使在开发中有一些问题迫切需要新的css 属性去解决,但是规范也需要花时间去考虑这个新属性对其他属性的影响,以及考虑如何命名及定义这个属性的规范,如果这个时候你着急用,浏览器厂商也想让你用,但是规范就是没出来,怎么办呢? 这个时候浏览器厂商,会先在自己的浏览器上实现,但会加上对应的浏览器前缀,以方便和后续规范中规定的属性进行区分,这就是浏览器前缀产生的原因. 当然这也是css 兼容性问题产生的原因之一.
4.最后,即使所有浏览器都按照同一个标准实现了 规范中的属性,但规范本身也是有可能犯错的,比如过了n 多年以后,规范发现之前的某个属性的定义可能不太适合现在浏览器的使用了,那怎么办,就只能修改规范,或者弃用这个属性,那浏览器也会在迭代中去适配规范,所以也会产生兼容性问题.还有,浏览器本身的迭代过程中,对某些属性的不一样的实现等等原因,都是产生浏览器兼容性的原因.
js 兼容性问题产生的原因
js 兼容性产生的原因,我感觉类似css 也会有css 的各种问题.
但js 兼容性问题产生的主要原因就是各个浏览器对js 的各种新语法的支持程度不同,比如有些浏览器对es6 的语法支持,一直不好,这个时候,你的代码如果是用最新的语法编写的,那这个浏览器就解析不了,就产生了兼容性问题.
3: 如何解决浏览器的兼容性问题
有问题不怕,有对应的解决办法就行,何况是对于 爱折腾的web 前端开发来说.
其实为了解决这些兼容性问题,我们的前辈们进行了很多努力,发展到今天,我们已经能够很容易的去处理这些兼容性问题,甚至当使用某些框架时,在你不清楚的情况下,框架已经帮我们处理了很多兼容性问题.
下面针对当前阶段,处理浏览器兼容性问题的方法做一个总结.
1.前端项目工程化的发展,尤其是webpack打包工具的出现,为解决兼容性问题提供了一个几乎完美的解决方案.
可以说webpack 打包工具一出现, web前端开发就有了光.
其实前面说了那么多废话,兼容性问题主要有两个,一个是css 兼容性问题,一个是js 兼容性问题 ,产生的原因归结来看,就是因为在开发过程中,大家采用了各种各样的技术框架,新语言特性 ,但不是所有的浏览器都支持这些技术和新的语言特性 .那么解决的办法也很简单,只要把我们开发的程序转化成各个浏览器支持的语言版本就行了 .而webpack 通过打包这个过程就能实现这种转化.
webpack 是如何实现转化的?
那么 webopack 为啥就这么牛逼,怎么就能把上述所有的兼容性问题就一下子解决了?
这个各位可以去webpack的网站上自行搜索详细信息.这里简单说下我的理解,个人认为可以把webpack 当成一个平台,这个平台集合了所有前端开发打包过程中遇到问题的处理工具,webpack主要是依赖于这些工具来完成各种各样的复杂操作的. webpack 的强大就在于对这些工具的集成.
针对浏览器的兼容性问题,webpack 通过集成babel这个js 转化工具来转化js代码,通过post-css 这个工具来转化css 样式,这样就完成了对浏览器兼容性问题的处理.
babel 工具
babel 简单来说就是一个编译器,通过识别我们写的高级语法,转化成低级语法,来完成对兼容性问题的处理.
babel 本身就是一个强大的工具,我们可以直接通过babel 的命令行工具,来完成对一些文件的转化.
另外,由于前端工程化的发展以及webpack 的集成,我们可以直接在webpack 的配置文件中,直接对babel进行安装配置,来完成对js 兼容性问题的处理.
在babel 中有很多处理高级语法的包,我们可以通过安装这些包,来处理各种类型的js 兼容性问题.
但是如果编译一个文件还好,如果要编译很多文件,就会很难用,并且还要安装很多不同的包,对心智的消耗很大,所以,babel 贴心的给出了 preset 工具,中文翻译是预设.
预设的意思是babel 把很多常用的处理兼容性的问题的包集合在了一起,我们只用安装这个预设,就能使用其中所有的包,来完成文件的转化.
下面是在webpack 中,使用babel 预设进行配置的流程,大家可以参考
1. 安装Babel核心包和Webpack的Babel loader:
npm install --save-dev @babel/core @babel/preset-env babel-loader
2. 创建或更新你的Babel配置文件(`.babelrc`或`babel.config.js`):
{
"presets": [
"@babel/preset-env"
]
}
3. 在Webpack配置文件(例如`webpack.config.js`)中添加Babel loader:
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
// 可以在这里指定额外的Babel配置,如果有的话
}
}
},
// ... 其他规则
]
}
// ...
};
至于babel 配置在单独的文件中,还是直接放在webpack 的配置文件中,大家看自己的爱好.
babel 工具的问题
使用上述的方法可以完成一些高级语法的代码转化,但是还有一些特殊的语法,使用预设并不能完成处理,这个时候,就需要使用另外一个工具,叫做prolyfill,中文翻译为 垫片.
垫片的作用是向目标浏览器中注入一些新的语言特性依赖的一些类或函数,使得浏览器最终能够解析我们用这些新的语言特性编写的代码. 比如 Promise, 使用babel 的预设是不能完成语法的转化,因为对他 的解析,需要有对Promise 概念对应的实现的类,而预设中包含的包只能对语法进行转化,并不能 注入这些类和函数,所以需要使用对应的prolyfill 来完成这个 过程.
1.安装
npm install --save-dev @babel/core @babel/preset-env babel-loader core-js
2.配置
// webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage', // 或者 "entry"
corejs: 3,
targets: {
browsers: ['> 0.25%', 'not dead'],
},
},
],
'@babel/preset-react', // 如果需要转换 React JSX
],
},
},
},
// ... 其他规则
],
},
// ... 其他配置
};
其中 useBuiltIns 属性是怎么使用垫片的设置,主要有false(不使用),usage(使用某个全局对象的时候注入),entry(把所有的对象都注入) .
post-css 工具的使用
在Webpack中使用PostCSS,你需要安装相关的插件,并在Webpack配置文件中配置。以下是一个基本的配置示例:
1. 安装包
npm install --save-dev postcss-loader autoprefixer
2. 配置
const autoprefixer = require('autoprefixer');
module.exports = {
// ... 其他webpack配置
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
autoprefixer({
overrideBrowserslist: ['> 0.15% in CN', 'last 2 versions'],
}),
],
},
},
},
],
},
// ... 其他rules
],
},
// ... 其他webpack配置
};
在这个配置中,postcss-loader
使用 autoprefixer
插件来自动添加浏览器厂商的前缀。你可以根据需要添加更多的PostCSS插件。