zoukankan      html  css  js  c++  java
  • webpack最佳入门实践系列(6)

    10.css模块化

    10.1.什么是css模块?

    CSS模块就是所有的类名都只有局部作用域的CSS文件,当你在一个JavaScript模块中导入一个CSS文件时,CSS模块将会定义一个对象,将文件中类的名字动态的映射为JavaScript作用域中可以使用的字符串,CSS模块不是浏览器中的官方标准(official spec) 或者 实践(implementation) 而是一个(在Webpack或者Browserify的帮助下)改变类名和选择器的作用域到当前文件(类似于命名空间)的构建过程

    通俗的说,css模块化,就是把css文件当作是模块来用,引入一个css文件的时候,得到一个对象,通过对象.类名的这种形式来使用css样式,这样做的好处就是所有类名都挂在了一个对象上,防止同名的类起冲突

    10.2.在webpack中使用css模块化

    首先,在src/assets/css/index.css文件中写入一段测试代码

    .pbox{
        border: 4px solid black;
        color: red;
    }
    

      

    在src/assets/js/index.js中写入一段测试代码

    // 引入icon图标字体
    //import "font-awesome/css/font-awesome.css"
    
    // 引入图片
    
    import imgSrc from '../img/nodeing.jpg'
    
    // 把图片插入到html网页中
    
    // document.getElementById("box").innerHTML = '<img src="'+imgSrc+'" />'
    
    // 测试css模块
    
    import styles from '../css/index.css'
    
    document.getElementById("box").innerHTML = `<p class="${styles.pbox} ">hello nodeing</p>`
    

      

    此时,运行npm start是看不到css样式的,我们必须在webpack.config.js中增加配置,开启css模块化才行,配置修改如下:

    {
        test: /.css$/,
        use: [
            'style-loader',
            {
                loader: 'css-loader',
                options: {
                    name: 'assets/css/[name]_[hash:4].[ext]',
                    module: true,
                    localIdentName: '[path]-[name]-[local]-[hash:base64:6]'
                }
            }   
        ]
    },
    

      

    配置修改后npm start运行就可以查看到css已经生效了,这上面的配置中

    module: true, 表示开启模块化

    localIdentName: '[path]-[name]-[local]-[hash:base64:6]' 表示定制类名称,[path]表示当前css文件路径,[name]表示当前css文件名称,[local]表示类名称(如:pbox),[hash:base64:6]表示base64的hash字符串,并且长度为6位

    接下来,我们去src/assets/js/index.js中,把图标字体的css文件注释去掉

    //import "font-awesome/css/font-awesome.css" 修改前
    import "font-awesome/css/font-awesome.css"
    

      

    修改了js文件,服务器会重启刷新,但是我们发现虽然我们引入了font-awesome.css这个文件,但是index.html中的图标仍然没有显示出来,以下是引用图标的html代码

    <i class="fa fa-bath" aria-hidden="true"></i>
    <i class="fa fa-envelope-open" aria-hidden="true"></i>
    <i class="fa fa-microchip" aria-hidden="true"></i>
    <i class="fa fa-user-circle-o" aria-hidden="true"></i>

    这些图标没有生效的原因是,我们在webpack中开启了模块化,开启了模块化功能后,使用样式的方式变成了"对象.类名"的形式,而在index.html中我们还在使用原来的形式,这样就不会有效果

    我们现在的需求就变成了:有些地方的css文件是需要开启模块化的,有些地方的css是不需要开启模块化的(例如:我们案例中的font-awesome.css文件),这个时候,我们需要去修改webpack配置,实现模块化文件的定制

    {
        test: /.css$/,
        use: [
            'style-loader',
            {
                loader: 'css-loader',
                options: {
                    name: 'assets/css/[name]_[hash:4].[ext]',
                    module: true,
                    localIdentName: '[path]-[name]-[local]-[hash:base64:6]'
                }
            }   
        ],
        //这条规则是需要开启模块化的,设置包含的文件夹
        include: [
            path.resolve(__dirname, 'src/assets')
        ]
    },
    

      

    我们在上面这条规则中配置了一条规则,include表示包含的意思,它的后面给一个数组,数组里面可以写一些路径,这些路径下的css文件就是需要开启模块化的css文件,既然是数组,那么就可以给多个路径

    修改过了配置文件,我们必须重启服务器才行,所以ctrl+c先关掉服务器,再通过npm start来启动,这个时候我们发现报错了,这时报错是正常的,因为,当我们在 ‘test: /.css$/’这条正则表达式规则下加了include包含的路径,那么意味着只处理了include包含路径下的css文件,而include以外的css文件并没有loader来处理它,所以,报了这样一个错误:

    ERROR in ./node_modules/font-awesome/css/font-awesome.css
    Module parse failed: Unexpected character '@' (7:0)
    //每次看到这句话,你就应该猜到要用对应的loader来处理对应的文件
    You may need an appropriate loader to handle this file type.
    | /* FONT PATH
    |  * -------------------------- */
    | @font-face {
    |   font-family: 'FontAwesome';
    |   src: url('../fonts/fontawesome-webfont.eot?v=4.7.0');
     @ ./src/assets/js/index.js 3:0-44
     @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/assets/js/index.js
    

      

    既然明白了报错原因,解决方案就非常简单了,我们去修改webpack配置文件

    {
        test: /.css$/,
        use: [
            'style-loader',
            {
                loader: 'css-loader',
                options: {
                    name: 'assets/css/[name]_[hash:4].[ext]',
                    module: true,
                    localIdentName: '[path]-[name]-[local]-[hash:base64:6]'
                }
            }   
        ],
        //这条规则是需要开启模块化的,设置包含的文件夹
        include: [
            path.resolve(__dirname, 'src/assets')
        ]
    },
    {
        test: /.css$/,
        use: [
            'style-loader',
            {
                loader: 'css-loader',
                options: {
                    name: 'assets/css/[name]_[hash:4].[ext]',
                }
            }   
        ],
        //这条规则是不需要开启模块化的,设置包含的文件夹
        include: [
            path.resolve(__dirname, 'node_modules')
        ]
    },
    

      

    从上面的配置,我们可以看出,解决思路很简单,就是我们把原来处理css文件的配置copy了一份,然后在copy的这份上做了修改,把css模块化设置去掉了,然后通过include设置了一个路径:path.resolve(__dirname, 'node_modules'),这个路径是第三方包的安装路径,我们的font-awesome.css文件就在这个路径下,意味着在这个路径下的所有文件都不会被模块化,这样就形成了一种结构,想让哪个路径下的文件不使用模块化功能,就在这个配置中添加路径就可以了,同理,想让哪个路径下的文件使用模块化功能,就在另一个css配置项中添加路径,到此,css模块化的基础内容就已经学完了

  • 相关阅读:
    【HTML5】元素<script>与<noscript>的使用
    【HTML5】元素<head>的使用
    【HTML5】交互元素menu&command元素
    【HTML5】summary交互元素
    【HTML5】用脚本控制交互元素details元素的使用
    【BIEE】页面跳转以及跳转后返回
    (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作
    哪些年是闰年
    工程师职称评定条件
    linux 网络编程-基础篇01
  • 原文地址:https://www.cnblogs.com/dadifeihong/p/8806989.html
Copyright © 2011-2022 走看看