首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >nextjs 写 css loader 处理多地区不同基础变量的方法

nextjs 写 css loader 处理多地区不同基础变量的方法

作者头像
蛋未明
发布于 2021-09-10 07:05:46
发布于 2021-09-10 07:05:46
1.6K00
代码可运行
举报
文章被收录于专栏:蛋未明的专栏蛋未明的专栏
运行总次数:0
代码可运行

由于项目在多地区进行发布,为了复用,主工程使用同一个,但是这样会带来一个问题,由于地区的设备分布不同,以及当地的字体选择不一样,从而导致了 global 中的一些熟悉无法复用,而且必须配置两套,那么如何来解决这个问题呢?

解决思路方法

由于项目中有一个非常基础的变量模块,暂且叫做 basic.scss ,然后在很多 scss 文件中都对该文件进行了引用,现在需要区分多个地区的基础配置,那么直接复制一份 basic.scss ,命名为 basic-[country].scss ,接下来就是要找到引用 basic.scss 的地方,然后在打包的时候将其替换为 basic-[country].scss 具体的国家或者地区就可以了。

那么这里就有问题是,怎么去找到这个文件,并且把引用关联找到,最后再替换,这种打包类的问题,当然 webpack 是首选。

webpack 选择

一开始思路是使用 webpack 来解决这个问题,那么到底是使用 loader 还是 plugin 呢?这里就需要去思考 loader 和 plugin 的区别。

这里引用一段说明:

作用不同

  • Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析非JavaScript文件的能力。
  • Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

用法不同

  • Loader在module.rules中配置,也就是说作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options)
  • Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。

其实看到第一段就有答案了,webpack 原生是只能解析 js 文件,如果想要其他文件也打包的话,就需要使用到 loader ,所以这里我们选择使用 loader 来处理。

loader 插件选择

在 loader 插件中有一个插件一下进入了视野,那就是 string-replace-loader 我们看下他的一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /fileInWhichJQueryIsUndefined\.js$/,
        loader: 'string-replace-loader',
        options: {
          search: '$',
          replace: 'window.jQuery',
        }
      }
    ]
  }
}

用法也比较简单,使用正则查询需要处理的文件,然后使用 string-replace-loader 来处理,参数第一个 search 查询需要替换的字符串,第二个是需要替换成的字符串。

想到这里,那么直接修改为下面这个方式不就可以了吗?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /[\s][\S]\.scss$/,
        loader: 'string-replace-loader',
        options: {
          search: 'basic.scss',
          replace: 'basic-[country].scss',
        }
      }
    ]
  }
}

如果你自己写的 webpack 插件确实是这样就行了,但是由于我们使用的是 nextjs 框架,webpack 是自动生成的,因此我们需要看看 nextjs 如何应用。

nextjs 接入

nextjs 官方有提供 loader 或者 plugin 的写法,以下是官方的例子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.mdx/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: '@mdx-js/loader',
          options: pluginOptions.options,
        },
      ],
    })

    return config
  },
}

按照官网的例子,我们修改下,改为下面这种 scss 替换的方式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /[\s][\S]\.scss$/,
      use: [
        {
          loader: 'string-replace-loader',
          options: {
            search: 'basic.scss',
            replace: 'basic-[country].scss',
          }
        },
      ],
    })

    return config
  },
}

修改完成以后,运行一下,你会发现解析其中会报错,而且要不就是说 css 解析不了,要不就是 less 解析不了,要不就是 js 问题等等。

看了下原因才发现,我们不能直接的 push 进去,而是应该在现有的 rules 的规则中增加该 loader ,那么接下来我们就来解决这个问题。

首先我们写一个方法,来添加这个 loader 规则:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 const addUserLoader = function(arr){
          if(!(arr instanceof Array)){return arr};
          arr.push(
            {
              loader: 'string-replace-loader',
              options: {
                search: 'basic.scss',
            		replace: 'basic-[country].scss',
              }
            }
          );
          return arr;
        };

接下来,我们需要去遍历当前所有的 rule 规则,我们先把所有的 rule 规则都加上这个,看看有没有问题,代码如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
webpackConfig.module.rules.forEach(
      rule => {
        if(rule.oneOf instanceof Array){
          let cssRules = [];
          rule.oneOf.forEach(cssRule => {
            if(cssRule.use instanceof Array){
              addUserLoader(cssRule.use);
            } else if(cssRule.use){
              addUserLoader([cssRule.use])
            }
            cssRules.push(cssRule);
          });
          rule.oneOf = cssRules;
        }
    
        newRules.push(rule);
    });
    webpackConfig.module.rules = newRules;
    return webpackConfig;

代码逻辑是比较简单的,遍历 rules ,rules 中 oneOf 非数组的不处理,数组的则进行遍历,判断 rule 下的 use 是否为数组,如果不是数组,说明是单个 loader ,那么先转化为数组,然后添加该 loader,如果是数组则直接 push 进去就可以了。

再运行一下,这样确实完成了,好了那么是否可以进一步优化呢?当然可以

优化方向

首先想到的是,我们不需要每个都增加该 loader,只需要正则能匹配 scss 结尾和 .global.scss 结尾的文件就可以了,认真看 nextjs 的 rules ,其中包含了一些以 .scss 结尾的规则和以 .global.scss 结尾以及不包含 .global 但是以 .scss 结尾的规则,那么这里有三个规则。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/\.(css|less|scss|sass)$/
/(?<!\.global)\.(scss|sass)$/
/\.global\.(scss|sass)$/
[ /\.global\.css$/, /\.global\.less$/, /\.global\.(scss|sass)$/ ]

为了适应这些规则,我们写一个方法一些判断就可以了,代码如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const checkNeedReplace = function(ruleTest){
     if(!ruleTest){
       return false;
     }
     if(!(ruleTest instanceof Array)){
       ruleTest = [ruleTest];
     }
     return ruleTest.some(rule => {
       if(rule.test('.global.scss') || rule.test('test.scss')){
         return true;
       }
     });
   }

由于 rules 也有是数组,有些不是,因此统一转化为数组,然后数组循环处理,判断是否存在一项满足条件的,使用 .global.scss 和 test.scss 去匹配,如果匹配就满足上面的正则条件。

有了上面方法,接下来我们只需要加一层过滤就可以了,代码如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
webpackConfig.module.rules.forEach(      rule => {        if(rule.oneOf instanceof Array){          let cssRules = [];          rule.oneOf.forEach(cssRule => {            if(!checkNeedReplace(cssRule.test)){ // 过滤不需要的规则              cssRules.push(cssRule);              return;            }            console.log(cssRule.test);            if(cssRule.use instanceof Array){              addUserLoader(cssRule.use);            } else if(cssRule.use){              addUserLoader([cssRule.use])            }            cssRules.push(cssRule);          });          rule.oneOf = cssRules;        }            newRules.push(rule);    })

以上就完成了,那么最后我们再来看一下全部代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
webpack: (webpackConfig, { dev, isServer, buildId, defaultLoaders }) => {    let newRules = [];    const addUserLoader = function(arr){      if(!(arr instanceof Array)){return arr};      arr.push(        {          loader: 'string-replace-loader',          options: {            search: 'vars.scss',            replace: 'vars-eurp.scss'          }        }      );      return arr;    };    const checkNeedReplace = function(ruleTest){      if(!ruleTest){        return false;      }      if(!(ruleTest instanceof Array)){        ruleTest = [ruleTest];      }      return ruleTest.some(rule => {        if(rule.test('.global.scss') || rule.test('test.scss')){          return true;        }      });    }    webpackConfig.module.rules.forEach(      rule => {        if(rule.oneOf instanceof Array){          let cssRules = [];          rule.oneOf.forEach(cssRule => {            if(!checkNeedReplace(cssRule.test)){ // 过滤不需要的规则              cssRules.push(cssRule);              return;            }            console.log(cssRule.test);            if(cssRule.use instanceof Array){              addUserLoader(cssRule.use);            } else if(cssRule.use){              addUserLoader([cssRule.use])            }            cssRules.push(cssRule);          });          rule.oneOf = cssRules;        }            newRules.push(rule);    });    webpackConfig.module.rules = newRules;    return webpackConfig;  }

如果你还有其他问题,欢迎一起交流学习。

参考文章:https://segmentfault.com/a/1190000037712654

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/06/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Ubuntu 文件文件夹查看权限和设置权限
-rw-r--r-- (644) 只有所有者才有读和写的权限,组群和其他人只有读的权限
用户5005176
2021/08/25
14K0
Linux权限详解 命令之 chmod:修改权限
在这种使用方式中,首先我们需要了解数字如何表示权限。 首先,我们规定 数字 4 、2 和 1表示读、写、执行权限(具体原因可见下节权限详解内容),即 r=4,w=2,x=1 。此时其他的权限组合也可以用其他的八进制数字表示出来,如: rwx = 4 + 2 + 1 = 7 rw = 4 + 2 = 6 rx = 4 +1 = 5 即
用户1214487
2018/08/01
6K0
Linux权限详解 命令之 chmod:修改权限
Linux操作系统创建新用户及用户权限
命令:useradd +用户名,它不会在/home目录下创建同名文件夹,也没有创建密码,因此利用这个用户登录系统,是登录不了的;
用户9104802
2021/11/22
5.8K0
Liunx的文件权限
之前讲过为了统一开发环境生产环境以及更换开发机器的情况,我把环境统一由Vagrant部署在Linux的虚拟机中,但是由于我对Linux系统没有系统的学习过,对于环境的部署也仅仅通过谷歌等刚刚入门,所以在具体的开发中我还是经常在Linux中遇到问题,经常求教老大。看着老大熟练的把玩Linux,我也下定决心要把Linux掌握好。
Originalee
2018/08/30
1.6K0
linux组管理和权限管理
在 linux 中的每个用户必须属于一个组,不能独立于组外。在 linux 中每个文件有所有者、所在组、其它组的概念
小小咸鱼YwY
2020/06/19
1.5K0
Linux 文件和文件夹权限
需要注意的一点是,一个目录同时具有读权限和执行权限才可以打开并查看内部文件,而一个目录要有写权限才允许在其中创建其它文件,这是因为目录文件实际保存着该目录里面的文件的列表等信息。
软测小生
2019/07/04
9.5K0
Linux 文件和文件夹权限
linux修改文件权限命令是什么_chown和chmod命令用法
Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作。
全栈程序员站长
2022/10/01
3.6K0
Linux系统下如何查看及修改文件读写权限
查看文件权限的语句:   在终端输入: ls -l xxx.xxx (xxx.xxx是文件名)   那么就会出现相类似的信息,主要都是这些: -rw-rw-r--   一共有10位数   其中: 最前面那个 - 代表的是类型   中间那三个 rw- 代表的是所有者(user)   然后那三个 rw- 代表的是组群(group)   最后那三个 r-- 代表的是其他人(other)   然后我再解释一下后面那9位数:   r 表示文件可以被读(read)   w 表示文件可以被写(write)   x 表示文
猿人谷
2018/01/17
11.4K0
Linux之权限命令基本使用
chmod u=rwx,g=rx,o=x 文件目录名 相当于 chmod 751 文件/目录名
兮动人
2021/06/11
1.5K0
Linux之权限命令基本使用
Linux读写执行(RWX)权限
一旦对目录拥有 w 权限,就可以在目录下执行 touch、rm、cp、mv 等命令。执行权限(x)目录是不能直接运行的,对目录赋予 x 权限,代表用户可以进入目录,也就是说,赋予 x 权限的用户或群组可以使用 cd 命令。
全栈程序员站长
2022/09/06
5.1K0
权力与优雅:Linux 权限的隐秘诗篇
Linux 是一种开源的、基于 Unix 的操作系统,它因其灵活性、稳定性和高性能而广泛应用于服务器、嵌入式系统、超级计算机、桌面计算等领域。
HZzzzzLu
2024/12/26
1830
权力与优雅:Linux 权限的隐秘诗篇
Linux 组管理和权限管理
在linux 中的每个用户必须属于一个组,不能独立于组外。在linux中每个文件有所有者、所在组、其它组的概念。
用户9615083
2022/12/25
1.9K0
Linux 组管理和权限管理
Linux系统中修改文件夹及文件读写权限
如果目录下的所有文件都需要以管理员的方式进行文件的复制,创建,和移动。比如我的data目录 ,此时只需要。
herve
2018/09/20
16.7K0
linux设置文件权限777_linux目录详解
Linux、Fedora、Ubuntu修改文件、文件夹权限的方法差不多。很多人开始接触Linux时都很头痛Linux的文件权限问题。这里告诉大家如何修改Linux文件-文件夹权限。以主文件夹下的一个名为“cc”的文件夹为例。
全栈程序员站长
2022/10/01
20.6K0
[802]linux修改文件或目录的所有者(chown)和用户组(chgrp)
文件或目录的用户组更改,注意:要更改的用户组,必须存在于“/etc/group”下
周小董
2020/05/13
26K0
Linux-权限管理(你听过777、755、644吗)
linux 中每个文件有所有者、所在组、其它组的概念。 类似linux 中的每个用户必须属于一个组,不能独立于组外,组的相关操作可参考:Linux-用户管理
唔仄lo咚锵
2021/09/14
3.8K0
Linux-权限管理(你听过777、755、644吗)
linux修改文件权限的命令_chmod递归修改目录权限
若没有某种权限,在该权限为会出现单破折线,这三组权限分别对应着对象的3个安全级别:
全栈程序员站长
2022/10/01
10.6K0
linux修改文件权限的命令_chmod递归修改目录权限
Linux文件权限
Linux文件权限 本文目录 1 拥有者、群组和其他人 2 文件的权限 3 目录的权限 4 root 5 更改所有者、群组和权限 chown chgrp chmod 5.1 chown 5.2 chgrp 5.3 chmod 6 umask 拥有者、群组和其他人 回到ls -al命令,该命令列出一个目录下所有文件的详细信息,下面是一个输出样例: drwxrwxr-x 5 tom tom 4096 May 29 2017 homework -rw-rw-r-- 1 tom tom 14 May
mwangblog
2018/07/04
10.3K0
linux chmod 755
chmod是Linux下设置文件权限的命令,后面的数字表示不同用户或用户组的权限。
全栈程序员站长
2022/09/13
4K0
Linux:权限相关知识详解
常用的基本指令已经讲解完毕啦:探索Linux世界:基本指令(文件查看、时间相关、grep、打包压缩及相关知识)
是Nero哦
2024/03/28
5680
Linux:权限相关知识详解
推荐阅读
相关推荐
Ubuntu 文件文件夹查看权限和设置权限
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验