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模块化的基础内容就已经学完了

  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/dadifeihong/p/8806989.html
Copyright © 2011-2022 走看看