前端模块化代码
有没有想过像Tuts +这样的大型网站如何在持续的开发和迭代过程中保持CSS,HTML和JavaScript的顺序? 我将向您展示我们为确保所有内容整洁和可维护而实施的过程。
CSS问题
这个过程的第一步是找到一种方法,以构建我们需要的大量CSS,而这些CSS不可避免地会陷入混乱。
传统上使用CSS,您可以根据需要建立样式,并努力使选择器广泛适用,以便可以在整个站点中重复使用它们。 例如,以下是一些简单CSS规则,这些规则在大多数样式表中都不会错位:
h1 { font-size: 22px; }
.subtitle { font-size: 18px; }
如果需要在页面的特定部分覆盖这些选择器,则可以使用嵌套规则来构造针对更特定元素的选择器:
.site-header h1 { font-size: 40px; }
.site-header .subtitle { font-size: 28px; }
.site-header a.navigation { color: #136FD2 }
...
这种方法在直觉上感觉是正确的,但是一旦您访问的页面超过几个页面,并且有多个开发人员正在工作,那么它可能会遇到一些重大问题。
当我们在全局级别更改h1
或.subtitle
的样式时会发生什么? font-size
已经被更特定的样式覆盖,但是如果我们添加font-weight
或line-height
,则不会。 对全局样式所做的任何更改都可能以不熟悉站点上所有样式的方式无法预测的方式波及并影响更具体的样式。
用这种方式构建的样式越多,交互CSS样式的“副作用”就越明显,需要进行繁琐的反复试验才能纠正,最终导致生产力损失和越来越多的错误蔓延到生产中。
BEM模块
为了帮助防止此问题,我们采用了基于BEM方法的 CSS 方法 。 取代定义适用于全球的样式,所有样式都通过命名约定隔离为独立的“块”。 “块”或多或少地被定义为潜在的可重用的单个独立的内容单元(尽管并非强制要求实际上可以重用)。
例如,让我们看一下“功能部分”块:
根据我们的命名约定,此块具有根div
元素,其类名称featured-sections
。 它包含具有类名称的元素,例如featured-sections__title
和featured-sections__section-link
。
我们为源代码使用了一个匹配的命名约定,因此,这个featured-section
块的所有样式都存储在modules/featured_section.sass
:
.featured-sections
margin: 0 0 $gutter-width 0
padding-top: 8px
border-top: 4px solid #dae1e5
.featured-sections__title
color: #8fa6b3
font: bold 14px/1.2em $font
此命名约定确保样式不再冲突和混合。 只要遵循我们的命名约定,并且在每个类名的开头加上块名,样式就不可能影响其自身块外的某些内容。
它还使在代码库中查找与元素相对应的样式的位置变得非常容易。 您只需查看元素的类名,就知道要打开的样式表的名称。
模块化查看代码
我们还选择了更进一步,并将此命名约定也应用于我们的视图。 每个块都有一个局部相同的视图名,存储在views/modules
。 例如,我们的featured-sections
块HTML视图位于views/modules/_featured_sections.html.slim
:
与为我们CSS文件指定命名约定可以很容易地找到CSS样式一样,为我们的视图拥有这种命名约定也可以很容易地找到视图代码。 当您在浏览器中查看页面并注意到需要进行某些更改的特定部分时,这非常方便。 您可以执行“检查元素”,并使用元素CSS类中清晰可见的块名称,以帮助您直接跳至相关的视图文件。
模块化JavaScript
在Backbone.js的帮助下,我们还继续为JavaScript代码采用了相同的命名约定。
每个需要应用JavaScript行为的块都使用相同的块名称获取一个Backbone视图对象:
class window.AccountHeader extends Backbone.View
events:
'change .account-header__mobile-menu-select': 'mobileMenuChange'
mobileMenuChange: ->
document.location = @_selectedOption().data('url')
_selectedOption: ->
@$ 'option:selected'
我们已经编写了一些页面加载时应用的视图加载代码,因此将使用CSS类为每个元素自动加载适当的Backbone视图,该CSS类与具有关联JS的块名称列表匹配。
我们也为我们JavaScript代码使用相同的文件命名约定,从而导致功能齐全的块的结构如下所示:
一般适用性
对于任何项目,我都强烈建议使用此方法。 我认为在处理大型项目时这是无价的,即使您在规模较小的站点上工作,以模块化方式构造前端代码也没有任何弊端。
也就是说,如果您已经拥有大量的全局CSS样式,或者如果您依赖于Twitter Bootstrap之类CSS库,则尝试使用此策略时可能会遇到问题。 由于BEM样式使用单个类名作为选择器,因此它们CSS“特殊性”值非常低,并且往往会被具有多个嵌套选择器以及标记名和ID的全局CSS样式踩踏。
从全球CSS风格转变为更具模块化的BEM风格绝对是可能的,从长远来看,我认为这是非常值得的。 但是,一定要花一点时间来构建您的BEM样式,并且准备在整个CSS中添加至少一些临时的!important
声明,直到您能够完全摆脱您的全局负担为止样式。
翻译自: https://code.tutsplus.com/articles/how-were-using-modules-to-organize-our-front-end-code--cms-22702
前端模块化代码