嘟嘟社区

[经验] 关于css能否写入js的问题,前端工程师普及一下


https://hostloc.com/thread-909625-1-1.html

这个帖子的主要内容就是建议开源作者把css写入js,其实建议没有问题,但是作者很敏感,认为是指他不会用webpack,感觉受到了侮辱。可以说是个误会。
但误会是如何产生的?其实作为开发了多年的老程序员,可以普及一下前端的真正含义。
我们买本书或者教程,都一直在强调,前端浏览器引擎是内置了html,css,js三个独立引擎的。
既然是独立引擎,那肯定浏览器在底层工作原理上就是区分出来的。
比如浏览器解析html,本身就是浏览器的基础功能,可以把文本模式的各种html标签按照功能需求直接渲染出来,比如img就是图片,video就是视频。虽然提供了js的API,但是并不是说禁用了js,这些标签就没办**常工作。

同理:css也是个独立引擎,其工作原理就是负责监听html引擎渲染的dom元素树,控制元素的颜色,大小,定位,背景,动画等等一系列为了美观的服务。特别注意的是,css是独立监听的。也就是你禁用浏览器js的情况下,同样是可以独立运行的。特别是底层涉及到repaint(重绘,局部样式构造),reflow回流(整体或者全局样式变更)的功能才是css最强大的地方,如果你一定要用js的原理来理解。其实就是你js动态添加的html元素,css同样生效。原理就是浏览器底层都是c语言开发的,其独立的监听功能实时性是js没办法比较的。

然后就是js了。其实可以说js是浏览器提供给开发者控制html,css的开发语言,也就是你这么理解,不可能提供给你浏览器原始c语言开发包。并且是唯一集成到浏览器的逻辑语言,注意,是唯一集成,不是最优秀。考虑到历史原因,实际上IE时代还单独集成了vbscript。只不过大家遵循w3c组织后,只剩下javascript了。

那ES和js有什么关系?ES是js的核心版本,你可以理解为是js官方提供的核心js版本语法,其一直在更新,所以现在有es5,es6,es7等等。但是浏览器端集成的js,不是ES官方同步的。也就是说,每家有独立开发能力的浏览器公司,其选择集成哪一个版本的js,是浏览器开发公司决定的。当然目前实际上主流浏览器只要还在更新的,基本都支持ES6语法了。也就是至少90%的ES6语法是支持的。特别注意的是,如果要在浏览器端完整理解js,其应该包括:ES+DOM(文档对象模型)+BOM(浏览器对象模型)三个部分。而如果你在node环境来执行js,是没有DOM+BOM的。

当然为了全面兼容市面上所有浏览器,比如 IE6-IE9,就必须考虑ES5的写法。但如果考虑到市场占有率,几乎直接在浏览器js中写入let 等ES6语法是没有任何问题的,甚至可以用fetch来代替XMLHttpRequest等js异步请求对象都是没有问题的。

js攻城狮 发表于 2021-10-28 12:26
一个CSS-IN-JS和CSS Modules的事儿。。。

这样也不正确,还是没有理解独立运行的原理。css-in-js就是用js来预处理,这肯定是文章反对的主要观点,其实就包括了css的预处理比如,less,sass等。
css modules其实也是类似的,只是操作办法符合文章推荐的js处理class的观点。
但是普及的原因是独立运行,不要去理解vue,react等提出的新的处理css的方式。
想表达什么呢?就是webpack打包是不必要的,不论是打包js还是css,也不论是提取出来单独压缩css还是直接写入js里面的css。
而是说,css本身不属于逻辑语言,就是可见即所得的层叠样式表。
你自己写入.css外部引用,或者内部引用,或者内联方式。都是可以的。

如果你是vue或者react的开发者,你可以单独写入一个.css文件,用class方式绑定,一点问题没有的。

问题出在哪里?问题就是现在的前端第三方框架,都想用js来操作css,模块开发,全局生效或者局部生效都是动态修改[a23adcasd]类似这样的唯一标识码,而实现绑定的。

也就是说,css是完全独立的,操作方式本身就是dom绑定的方式,由于vue,react等开发者习惯了mvc的理念,无法理解为何还要单独操作dom的步骤,所以把css理解为了逻辑语言,是js的一个子功能,才是问题的关键所在。

竟然为了这个 说了这么多。大佬就是大佬。

不过我是不建议把css写入js。感觉上维护起来很麻烦。
而且写入js没有什么意义。

本帖最后由 kaleok 于 2021-10-28 10:56 编辑

那你理解了上面的内容,webpack到底做了什么?webpack其实就是在你的电脑,首先安装node环境,同样配置好了mime类型,然后vue的开发者才会用build命令,做了一次解析多个目录,把所有.vue后缀的文件打包到了一个js当中而已。

注意:我并没有用编译这个词,而是用了打包。这里就说一下坏处了。用webpack打包压缩的vue项目很简单了,一个index.html,加上多个打包压缩后的.js。就可以发布了,当然中间肯定做了ES5语法替换,去除空格,压缩,甚至可以做到加密。但是问题就是这样做的前端项目出现一下几个问题:
1、你开发的模块越多,特别是npm加载的第三方组建越多,你自己可以看看每次你打包时多少个文件就明白了,只要你用到的组建,即使只用了其中一个很简单的功能,但npm发布的作者代码量都非常大,你可以看到每次打包都是几千个组建被加载,那代码的量就更恐怖。所以也就是webpack打包的项目由于.js的代码量巨大,一般都是几M几十M的单位,首次加载网页白屏,需要等待很久原因就在这里了。如果你是买的1M的国内VPS,10M的js,你可以算一下一个人访问时需要花多少时间才能加载完成,多人访问时需要多少时间才能加载完成。

2、现在都是开源时代,特别是前端,html,css,js,在vue,react,angular没有出来之前,没有人考虑加密的,及时是js加密,也可以理解为保护核心功能而已。但css,html文件都是独立的。因为你再如何折腾,浏览器只要渲染成功,都可以打开控制面板看到html代码和css代码。

3、打包的必要性和编译的理解。很多静态语言为什么要编译?编译的目的是转换为二进制,脱离执行环境,直接交给系统,操作CPU,提高执行效率。
webpack打包出来却只是压缩。
4、代码维护变困难,比如以前开发html+css+js最终执行都是放入浏览器三个核心解析器来执行。也就是你根本不需要搭建什么后端环境,直接桌面拖拽.html文件到浏览器就能执行。现在变成了,先安装个node环境才能开发前端,node 是后端环境哦。。。。并且整个开发流程,你只是为了用webpack打包,或者npm下载别人开发好的组建直接用时才会用到。。也就是整个项目的代码质量非常差,很多都是第三方组建,npm是个人都能发布,你没办法知道你每行代码的必要性,产生了很多冗余代码。并且还开启了一个本地后端ndoe环境。。。实在违背了大前端(女权,男权)一定要前后端完全分离的思想。
5、就是seo问题了,前端极端者(大前端,类似女权,男权的人),总是强调前后端完全分离,但开发时却用了node后端环境,然后理解是js的后端环境,所以又提出js天下第一。。。但最头疼的问题是,如果你是大公司,多个node服务器是极其简单的事情,如果你是小公司,开发出一个作品,切不被收录,确实有点自娱自乐的感觉,那单独搞个node服务器?搭建ssr与处理渲染?是不是有点把简单的事情复杂化了?我并不反对vue,观念很好,你可以直接局部虚拟化嘛,或者用jquery?或者自己写js?没有什么落伍的,一切都是为了考虑开发效率和成本。如果你稍微理解一下后端mvc架构,早就是实现了前后端分离,只是不够彻底,需要你自己熟悉一下模板语言的语法而已。。
更何况,大家几乎除了大公司网页,在搜索引擎能找出来的网页都是传统开发方式,比如你们最熟悉的wordpress,discuz等等。。。
自己就在一个传统开发方式的论坛,为什么找开源产品就这么极端?一定要webpack的才觉得不丢人?好好思考一下这个问题先。

以上我们算是基本理解了js,ES,VUE等的概念,那跟css有什么关系?
你可以这样理解,html,css,js是完全独立运行在浏览器引擎中的,你可以做个实验,单独写css代码,然后用js动态添加删除dom元素,你会发现,动态添加的dom同样被css监听到,css的效果同样起作用了。
那你把css写入到js目的是什么?

如果你理解了独立运行的概念,把css写入js,就好比,人家本来好好引擎级别的C语言监听dom变化的,你非要拿个脚本js逻辑语言来处理css,但你也只能做到,动态加入css代码到引擎,也就是,你只是用 js,到底什么时候写这个css代码,而没有做到任何优化动作。
所以正确的使用js操作css的办法,我们一直是用js来动态添加class或者删除class,因为理解了独立运行,没有什么办法比原生css的执行能力强,所以写动画,都是推荐用css编写动画而不用js来编写动画的原因也在此。

后面还有很多,已经丢失了。。。我也懒得再说了。

其实有很多丢失了。。论坛帖子最多1万字,还触碰到非法关键词,所以没注意分割时丢失了。我单独补充一下,为什么开源作者会这么敏感的问题,因为你如果认同了我上面说的,你会发现码农跟有独立开发能力的开发者区别还是蛮大的,因为开发者至少知道底层工作原理,才能开发出市面上不存在的东西。而码农的定义就是只要是涉及到工作中的项目不论难度是否大,首先想到的是github,npm等等开源库看看有没有现成的,或者就是搜索引擎查找,但是作为一个有独立开发能力的人,肯定是需要知道自己每行代码的含义的。npm,github有很多大神,但也有很多参差不齐的发布者,代码质量和代码冗余性,以及安全性都是没办法保证的,比较没有官方审核,只要你有账号就能发布。所以如果好不容易开发出一个独立作品,却被不懂行的人质疑,实在是有点憋屈,所以敏感,极端也是可以理解的。但心态不好。就如大家所说,观念不同而已。用人家的组建拼拼凑凑就能出一个项目,何必一行一行代码写呢?但是,问题就是现在行业氛围导致说出多了解一下原生,这样一个多么普通的基础原理,都被口诛笔伐,只能算是行业悲哀了。时代变了,买本书看看原理的时代已经过去了。没人关心什么基础,甚至觉得高校教的基础都是垃圾,拿个UI框架,后端框架调用两下就出来的东西,就是比自己写的优秀的观念占了主流,着实没有想到的。

论坛限制太多了。发了三贴,还有关键词。。。。处理了大半天才发布出来

本帖最后由 kaleok 于 2021-10-28 11:56 编辑

那js,vue,jquery又是什么关系?

vue没有出来之前,jquery是代替原始js绑定html dom元素最简便的方式。但是其开发时程序员手写代码的难度比较大。一个很直白的场景,比如一个动态表格,异步获取数据以后,你需要类似

  1. var data ;
  2. var html += ‘<tr>’+;
  3. html += ‘<td>’+data.id+'</td>’+;
  4. html += ‘<td>’+data.name+'</td>’+;
  5. html += ‘</tr>’+;

复制代码

先编写变量,插入数据对象的值后,再渲染到dom当中,从编写角度来说,确实很low;

而vue react angular出来以后,这三个提出了与传统开发不同的概念,就是前后端完全分离,包括路由重写(实际上就是单页面模拟多页面的浏览器超链接构造),数据获取,数据渲染。等等核心思想就是mvc概念,但有些又优化了概念,比如mvvc等等。双向绑定的含义。
反正一句话就是,开发者不用再去手动创建变量拼接html代码,然后操作dom,而是由底层负责创建全局虚拟化的dom,然后利用js本身的ES5的defineProperty,ES6的proxy 两个监听对象就能实现全局内存中js的全局虚拟化dom了。

这里特别要注意,就是vue,react,angular没有发明出什么,是利用了js的高级API,做到了完全独立的,类似于后端的mvc面向对象开发的的新的开发方式。也就是你可以理解为,当然浏览器集成js的目的就是方便开发者操作dom的,并没有提倡搞什么全局虚拟化,你们应该听说过js局部异步渲染,没有听过全局异步渲染,原因就在此。

那这种全局虚拟化的好处有哪些?坏处有没有呢?

好处就是:1、多出一个独立的工种,就是前端工程师。因为开发方式跟后端一样,可以理解为js变成了一个在浏览器端完全自主开发的面向对象开发方式的程序员必备了。(坏处:但是。。。。mvc不就是后端最擅长的么?比如路由重写,但入口,控制器,视图,模型20年前就这样做了。vue,react,angular算不算重复造轮子了?)
2、全局虚拟化以后的html dom对象,被js接管实时监听,然后获取数据,挂载到内存的虚拟dom中,其实就是利用mvc,如果是双向绑定,就是用户点击页面已经实体渲染的html元素,又会把变化响应到data数据对象中,那就是mvvc。(坏处:但是:全局虚拟化并没有完全脱离不去操作dom,只不过是所有的细节dom操作都在内存虚拟dom操作,最终结果才会真实操作实体dom,比如vue有一个 id="app"的实体标签,就是方便最终由虚拟dom一次性挂载到真实dom而设置的实体入口标签)

3、利用webpack打包压缩前端任何文件,发布时只会剩下一个index.html入口文件,和n多个js文件,好像与css就无关系了。(坏处:注意,webpack是个独立的打包工具,并且他的工作原理是node环境下的js逻辑语言开发的一个独立软件。。。所以很多前端开发者一直不能理解清楚webpack的真正用途。)

webpack是什么,单独说一下吧。也就是你开发的vue其实是可以直接引用vue.js就可以单独在一个普通html文档开发的。但是为了更像后端程序员面向对象开发一样,可以创建多个目录,每个目录不同的模块,在利用es6的多文件import导入,就非常像一个独立的项目了。
但是要发布时,是不是要上传很多很多的目录和文件?特别是.vue后缀的怎么办?默认服务器根本不支持解析.vue后缀的文件呀。(当然涉及到服务器是否能解析一个特定后缀,需要配置mime类型。。。也就是apache,nginx等你只需要修改mime.types文件内的解析后缀,同样是可以解析.vue文件的,也就是说,你根本不需要webpack打包,就这样上传多个文件夹的.vue文件上去,修改好.vue后缀就解析成javascript脚本文件,同样是没有任何问题的。)

@逸笙  代码举例是针对数据处理时的方式不同,如果是vue,不需要关心渲染的过程,但是如果是传统js,就需要自己写插入入口,举例代码还少了一句:$(‘#tbody’).html(html);这样就跟jquery又关系了吧

逸笙:你这上文,我只能理解你在这打算举个jq例子,但我没看到,只有手写html

请更严谨行文

楼主:你这样来反驳就有点过了,要更正你可以单独发帖,为什么要来纠正我认为对的,你认为错的事情呢?你的观点不认同我,就需要我来更严谨的行文?你是谁呀?

如果你用过传统开发方式,动态表格,里拼接html就+号补充,单引号补充,如果代码片段比较大,都非常花时间,这就是我说的传统开发方式在数据处理时确实不如vue等全局虚拟化的地方。但是文章已经很客观的说了,vue全局虚拟化会带来更多问题,局部虚拟化本身也是js异步的核心

观念不同而已

你把css压缩到js里面就更完美了,你看那些用的多的插件,都是将css压缩到js里面的,这样子引用插件,就只需要放一个js即可

原文是这样说的, 确实将 css 插入 js 中可以只单独引用一个 js 就可使用整个模块.

立场不同吧.

还是大佬分析的透彻

ouou8 发表于 2021-10-28 10:44
竟然为了这个 说了这么多。大佬就是大佬。

不过我是不建议把css写入js。感觉上维护起来很麻烦。

同感,还要再打包一遍,但凡有点修改,每次发布都这么弄,那也太烦了
感觉把css打入js是那种前段极端分子的写法,总是强调一个文件,减少并发数量到了极致的一种体现
真没什么必要,现在机器性能够
而且,影响我开发体验的通通滚蛋,我写的代码,我说了算,不服不要玩,

感谢,受教了
打这么多字辛苦了
后排围观大佬。