(new)webpack4+react 脚手架

前提: 安装webpack、webpack-cli

一、首先先让出来一个页面有内容

  1. 先添加.gitignore,将git该忽略的文件列出来;
  2. 由于之前对webpack做的事情进行了练习,因此,直接让webpack打包出bundle.js文件,新建index.html,将打包文件手动引进<script>,配置webpack构建文件的输入输出。即,页面就会正常出来,不过是通过本地html文件打开的。

二、想实现实时预览功能(安装webpack-dev-server)

背景:使用本地文件每次改变后都需要手动刷新页面,希望做到如下:

  • 提供HTTP服务而不是使用本地文件预览;
  • 监听文件的变化并自动刷新页面,做到实时预览;
  • 支持source map,以方便调试。

背景:步骤:

  1. 在npm scripts里面使用 webpack-dev-server --config 配置文件路径名(相应的代码会读进内存,不会在当前目录下产生dist文件夹,使用webpack命令+配置文件路径名,才会有dist文件生成)启动编译功能;
  2. 启动成功后,会有默认的本地域名以及端口http://0.0.0.0:8080/;
  3. 当然,还需要在配置文件里配置DevServer,并将public里的index.html文件引用的bundle.js改为绝对路径,这样才可访问到域名,并将页面内容显示出来;
devserver: {
  // 服务器可访问文件;
  // 后面构建步入正轨,自动将index.html加入dist文件后,则会将`../public`更改为:/ dist
  contentBase: path.resolve(__dirname, '../public') 
}
  1. devserver启动webpack本身就实现了实时预览,为了实现模块热替换,还需进行配置以下:
devserver: {
  hot: true, // 开启热模块替换(必须配合inline一起使用)--实现实时预览
  inline: true, // 可以单独使用 --实现实时预览
}

三、在打包文件dist文件下自动生成index.html文件,并将编译好的js文件动态添加进html文件里。

  1. 安装html-webpack-plugin
  2. 这个插件可以直接在dist文件下生成index.htm文件,并将打包好的bundle.js文件引入。
plugins: [
    // 生成的html文件是默认的title,可通过配置更改
    new HtmlWebpackPlugin({
         title: 'react project' 
    })
]

四、如何按照public里的index.html生成dist里的html页面入口文件

  1. 查看HTML Webpack Plugin文档,进行如下配置,然后删掉原来public里index.html引用的bundle.js
plugins: [
   new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html'), //模板html文件
      filename: 'index.html' //在dist文件夹的文件名 
   })
]
  1. development 和 production的而配置文件都要写。

五、统一代码风格

  1. 添加.editorConfig配置编辑器
    (1)首先确保编辑器安装了EditorConfig插件
    (2)其次在.editorConfig文件里添加属性配置(属性查看更多

    基础配置

  2. 添加.eslintrc进行代码风格校验
    (1)安装eslint,eslint-loader(为了支持在编译代码时进行eslint校验),babel-loader(为了支持eslint配置进行代码校验,必须安装,不安装的话会报错:error Parsing error: Unexpected token path,加上后编译立马成功)
    (2)在.eslintrc文件里进行检验规则配置(配置查看更多),安装`babel-eslint对eslint进行解析,有了eslint校验规则,写代码会舒服很多。
    (3)eslint特点

  • ESLint 使用 Espree 解析 JavaScript。
  • ESLint 使用 AST 去分析代码中的模式
  • ESLint 是完全插件化的。每一个规则都是一个插件并且你可以在运行时添加更多的规则
    (4)eslint配置项【查看文档
  • root: 限定配置文件的使用范围
  • parser: 指定eslint的解析器
  • parserOptions: 设置解析器选项
  • extends: 指定eslint规范
  • plugins: 引用第三方的插件
  • env: 指定代码运行的宿主环境
  • rules: 启用额外的规则或覆盖默认的规则
  • globals: 声明在代码中的自定义全局变量

如下是还没添加任何页面的项目的简单配置,使用的是eslint:recommend:

{
    "env": {
        "browser": true,
        "node": true
    },
    "extends": "eslint:recommended",
    "parser": "babel-eslint",
    "rules": {
        // Recommend not to leave any console.log in your code
        // Use console.error, console.warn and console.info instead
        // https://eslint.org/docs/rules/no-console
        "no-console": [
            "error",
            {
                "allow": ["warn", "error", "info"]
            }
        ]
    }
}

后期使用什么再继续研究、添加吧!

六、(git hooks)想实现在代码提交(git commit)前对代码进行eslint检查

  1. 用到的工具:husky、lint-staged、commitliner、prettier
  2. 各自的概念 && 作用:
  • husky:(husky 为 git commit 增加钩子)
    (1)其实就是一个为 git 客户端增加 hook 的工具。将其安装到所在仓库的过程中它会自动在 .git/ 目录下增加相应的钩子实现在 pre-commit 阶段就执行一系列流程保证每一个 commit 的正确性。
  • lint-staged:(只是平台,搭配其他工具使用 --- 将错误过滤出来,禁止提交,进行提示)
    (1)Lint-staged仅仅是文件过滤器,不会帮你格式化任何东西,所以没有代码规则配置文件,需要自己配置一下,如:.eslintrc、.stylelintrc等。
  • commitlint:(优雅的提交,方便团队协作和快速定位问题)
    (1)为了方便开发团队协作开发,commit -m 中的提交【信息】需要有个规范,方便直观的看出每次commit 的目的。
  • prettier:(prettier 保证每个团队代码格式一致性 --- 自动格式化)
    (1)不论你写的代码格式是什么样子,只要你想提交,就必须格式化成 prettier 要求的样子,这样就没有那种因为格式变动出现的无聊的 diff 了。
    (2)而ESLint 只在发现问题的地方进行 fix,这是两者在逻辑上有区别。
    (3)prettier让我们专注于业务逻辑,无需再纠结代码风格,配合其它工具,实现了代码提交到仓库前,统一格式化。
  1. 这四个都需要进行安装:npm i -D husky lint-staged commitlint prettier
  2. 先实现一个基本的husky使用
    安装了husky后,需要在package.json中进行配置(参考),必须要配置husky,如下配置后,当在git commit 的时候就会去调用钩子进行校验,不配置则不会进行校验。
"scripts": {
    "lint": "eslint \"src/*.js\""
},
"husky": {
      "hooks": {
          // 打印出“husky222”以及运行script中的lint命令,对src文件下的js文件进行eslint检查
          "pre-commit": "echo 'husky222' && npm run lint"
      }
  }
  1. 使用 huskylint-stagedprettier 集成配置(进行代码检查 与 格式化配置)
    实现过程:
    (1)待提交的代码
    (2)git add 添加到暂存区
    (3)执行 git commit
    (4)husky注册在git pre-commit的钩子调起 lint-staged
    (5)lint-staged 取得所有被提交的文件依次执行写好的任务(ESLint 和 Prettier)
    (6)如果有错误(没通过ESlint检查)则停止任务,等待下次commit,同时打印错误信息,如果添加eslint --fix以及prettier,则会自动格式化代码。
    (7)成功提交
"lint-staged": {
    "src/**/*.{js,jsx}": [   // 对src下面的js、jsx文件进行校验
        "prettier --write",  // 进行eslint校验,格式化错误文件,--write直接改写(按照prettier格式化)文件
        "eslint --fix", // 进行eslint校验,--fix进行错误修复
        "git add"    // 将处理过的代码重新 add 到 git 中。
    ]
  },
"husky": {
      "hooks": {
          "pre-commit": "lint-staged"
      }
  }

// *** 整理 ***
// prettier --write 和 eslint --fix配合使用,也可单独使用,几乎是相同的效果。
// (1)prettier --write 和 eslint --fix-------则会进行格式化,同时提交成功。
// (2)prettier 和 eslint -------则不会进行格式化,同时也不会提交成功。
// (3)prettier --write 和 eslint -------则会进行格式化,同时也会提交成功。
// (4)prettier 和 eslint --fix  -------则会进行格式化,同时也会提交成功。
// (5)只有prettier ,没有 eslint --fix  -------则不会进行格式化,但是会提交成功,提交到仓库中是有错的代码,因此,在配置的时候必须写上--write。
// (5)没有prettier ,只有 eslint   -------则不会进行格式化,并且不会提交成功,说明只是进行eslint校验提示而已。


  1. 使用commitlint,进行配置,常规提交
    (1)安装
    npm i -D @commitlint/config-conventional @commitlint/cli
    (2)命令行生成配置文件commitlint.config.js
    echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
    echo生成的commitlint.config.js内容如下:
module.exports = {
    extends: ['@commitlint/config-conventional']
}

(3)配置(添加这个,才开始进行提交检测)
在husky的配置中加入CommitIint配置,v1.0.1版本以后为HUSKY_GIT_PARAMS,v0.14.3为GIT_PARAMS

"husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }

(4)定制提交规范

  • 提交格式:<type>: <subject>
  • type:用于说明 commit 的类别,只允许使用下面7个标识(其实还有一些其他的)。
    如果type为feat或者fix,则该 commit 将肯定出现在 Change log 之中。
  • feat:新功能(feature)
  • fix:修补bug
  • docs:文档(documentation)
  • style:样式(不影响代码运行的变动)
  • refactor:重构(既不是新增功能,也不是修改bug的代码变动)
  • test:增加测试
  • chore:构建过程或辅助工具的变动
  • subject:是 commit 目的的简短描述,不超过50个字符,且结尾不加句号(.)
    示例1:git commit -m 'package.json配置commit-msg',提示报错,缺少<type><subject>
    示例2:git commit -m 'feat: package.json配置commit-msg',即可提交成功

(5)commitlint.config.js文件配置
rules配置说明:rules由name和配置数组组成,如:name:[0, 'always', 72],数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error;第二位为应用与否,可选always|never,第三位该rule的值。具体配置例子如下:

module.exports = {
    extends: ['@commitlint/config-conventional'],
    rules: {
        'type-case': [2, 'always', 'lower-case'],
        'type-empty': [2, 'never'],
        "type-enum": [
            2,
            'always',
            [
                'build',
                'chore',
                'ci',
                'docs',
                'feat',
                'fix',
                'perf',
                'refactor',
                'revert',
                'style',
                'test'
            ]
        ],
    }
}

七、添加react语法

(1)安装react react-dom
(2)写react-jsx页面的时候,运行会报错,需要安装babel来解析react的jsx语法


(3)安装完babel-loader babel-core babel-preset-2015 babel-preset-react后,在webpack.config.development.js里配置:

   {
      test: /\.js$/,
           use: [{
                    loader: 'babel-loader',
                    options: { presets: ["react","es2015"] }
                }],
           exclude: /node_modules/
   }

(4)配置完后还报错,其实是eslint的报错


(5)将eslint配置里的"extends": "eslint:recommended"换成"extends": "airbnb",则js文件就不报错了。
(6)然后再次运行,又报错

(7)可以看出来,需要安装eslint-plugin-jsx-a11y(注意:a11y 不是 ally,安装了半天,导致安装不成功,唉~~哈哈)来支持airbnb的工作。
(8)然后再次运行,又报错

(9)由于项目中应用了ES6import,并且报错提示,需要安装eslint-plugin-import来通过 airbnb 对es5es6import/export进行 eslint 校验,并防止文件路径和导入名称拼写错误。
(10)安装好之后,接着又报其他错:

(11)上网搜了一下后,说是babel依赖包版本(6,7)不兼容导致的,因此,解决方法将其babel升级到7试试,做了步骤如下:

  • 卸载掉版本6:npm un babel-core |npm un babel-preset-es2015|babel-preset-react
  • 安装新版本7:npm i -D @babel/core @babel/preset-react
  • 将项目node_modules删掉,重新安装所有依赖npm i,更新最新的node_modules依赖包。

(12)webpack里面也需要修改,这样就ok了

{
   test: /\.js$/,
   use: [{
        loader: 'babel-loader',
        options: { presets: ['@babel/react'] } // 重新修改babel的preset
   }],
   exclude: /node_modules/
}

(13)然后再重新运行,发现只有eslint的报错,将eslint进行自定义配置后,成功运行项目。
(14)将webpack里的babel配置抽离出来,写在.babelrc文件里

// .babelrc文件
{
    "presets": ["@babel/react"]
}

// webpack文件(开发 and 生产)去除options选项
{
   test: /\.js$/,
   use: [{
        loader: 'babel-loader'
   }],
   exclude: /node_modules/
}

(15)本次react加入over了!!

八、添加antd样式

  1. 安装antd npm i antd --save
  2. 看看antd可不可以用,修改

index.js:

import React from 'react';
import ReactDom from 'react-dom';
import { LocaleProvider } from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';
import App from './app';

// locale={zhCN}:由于 antd 组件的默认文案是英文,所以需要修改为中文
ReactDom.render(
    <LocaleProvider locale={zhCN}>
        <App />
    </LocaleProvider>,
    document.getElementById('root')
);

app.js:

import React from 'react';
import { DatePicker } from 'antd';

const App = () => <DatePicker />;
export default App;

  1. 没加locale={zhCN}时,则日期里默认的文案为英文,加上之后就会是中文了。

    未添加(locale={zhCN})文案默认英文

    添加(locale={zhCN})文案默认为中文

  2. 通过查找资料,发现网上说import { DatePicker } from 'antd'这样写会引入antd下的所有的模块,这会影响应用的网络性能,因此需要babel-plugin-import来进行组建的按需加载,否则项目会打包整个组件库,非常大。
    (1)安装:npm i -D babel-plugin-import
    (2).babelrc

{
    "presets": ["@babel/react"],
    "plugins": [
        [
            "import",
            {
                "libraryName": "antd",
                 // 一般为:“style”: “css”;
                // “style”: true 时会加载less文件
                "style": true 
            }
        ]
    ]
}
  1. 重新运行,发现报错提示:需要用loader来加载各种.less文件。


    加载less文件报错
  2. 因此,进行样式loader的安装与配置。
    (1)安装:npm i -D less-loader css-loader style-loader
    (2)webpack配置如下:
{
   test: /\.(css|less)$/,
   use: [
          'style-loader',
          'css-loader',
          'less-loader'
   ]
}
  1. 重新运行,发现又报错:


  2. 尝试安装一下less模块。
    (1)安装:npm i -D less
    (2)重新运行,发现又报错:
  3. 通过提示Inline JavaScript is not enabled. Is it set in your options?在webpack里进行less选项设置:
{
     test: /\.(css|less)$/,
     use: [
            'style-loader',
            'css-loader',
             {
               loader: 'less-loader',
               options: {
                     javascriptEnabled: true      // 添加后,正常运行,antd样式也生效了
                }
              }
      ]
}
antd样式生效啦~~
  1. 想让自己添加的样式文件(.less)生效,如下:

react的className属性自带的,直接用。。


app.js
app.less

自定义样式生效

(1)将.less文件改为.css依然生效。。。因为webpack正则里面两者都有。
(2)去掉css可以编译成功,但去掉less就不行了。
(3)但如果将webpack正则里的less去掉的话(或者:添加exclude: /node_modules/),就会报错,因为antd里的样式文件也有less格式,需要进行匹配、解析。

九、打包并做分离js、css

现在项目中有了样式文件,打包后发现js和css文件都在一个文件bundle.js里打包着,(那么页面加载的时候会先解析完了js之后再去加载css,这样会影响用户体验,所以我们需要将css单独提取出来,以link的方式注入到文件里面)做以下事情:

  1. 针对webpack 4,使用的是mini-css-extract-plugin插件,来进行分离打包js和css,(每一个js文件只要包含css文件,就会创建一个css文件)。
    安装:npm i -D mini-css-extract-plugin
  2. 在配置之前,再安装一个插件npm i -D clean-webpack-plugin,用来删除旧的dist打包文件,以便后面进行测试。配置如下:
const CleanWebpackPlugin = require('clean-webpack-plugin');
// 尝试过给dist里面添加一个aa.js文件,重新打包,会生成不含aa.js的新的dist文件
plugins: [
     new CleanWebpackPlugin()
]
  1. 好了,接下来就要开始分离css的配置了。

webpack.production.config.js文件:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

plugins: [
     new MiniCssExtractPlugin({
         filename: '[name].css', // 只有入口文件才打包成这个格式
         chunkFilename: '[id].css'  // 非entry全部打包成这个格式
     })
]
filename:[name] 和 chunkFilename:[id]的解释
  1. 将所有打包路径整理一下
    (1)原因:之前是直接将所有的文件都打包在dist文件下,后期如果文件多了,打包后会很不好查看和管理,因此需要将构建文件进行分类打包管理,给人一目了然的效果。
    (2)将css、js、images、dll文件都放在dist/public/下,除index.html外。
    配置如下:暂时只涉及到这两处(css、js),后面添加的也是这样配置。
  • 解释(index.html为什么不能放在public文件夹下):
    由于一般index.html打包后都是直接在dist文件夹下,所以项目启动后,直接打开localhost:8080就可以直接看页面效果,但是现在我们把它放在了/dist/public/下,导致打开的页面是一个public文件夹,说明localhost:8080所指向的是dist文件夹下的index.html,因此,配置html不能放在public文件夹下。原因如图:

    配置将index.html放在public问价夹下

  • 需要在output里设置publicPath: '/',来达到将index.html里导入的scriptcss设置为绝对路径/public/...。如下所示:

配置publicPath: '/'

(3)filename没有chunk后缀名,chunkFilename有chunk后缀名。
(4)development里文件不需添加 hash,production需要添加hash
(5)如下为production文件关于(打包和分离js、css)的配置。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: {
        app: path.resolve(__dirname, '../src/index.js')   // 设置入口名:app
    },
    output: {
        filename: 'public/js/[name].[hash:8].js',   // 入口js输出文件名
        chunkFilename: 'public/js/[id].[hash:8].chunk.js', // 非入口文件名
        path: path.resolve(__dirname, '../dist'),
        publicPath: '/'     // 加载异步资源的url地址
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: [{
                    loader: 'babel-loader'
                }],
                exclude: /node_modules/
            },
            {
                test: /\.(css|less)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: 'less-loader',
                        options: {
                            javascriptEnabled: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html'),
            filename: 'index.html'  // 不能放在public文件夹下,需直接放在dist下
        }),
        new MiniCssExtractPlugin({
            filename: 'public/css/[name].[hash:8].css', // 入口css文件名
            chunkFilename: 'public/css/[id].[hash:8].chunk.css' // 非入口css文件名
        })
    ]
};
打包文件夹

(6)如下,再贴一下development的配置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        app: path.resolve(__dirname, '../src/index.js')
    },
    output: {
        filename: 'public/js/[name].js',
        chunkFilename: 'public/js/[id].chunk.js',
        path: path.resolve(__dirname, '../dist'),
        publicPath: '/'
    },
    devServer: {
        hot: true, // 开启热模块替换(必须配合inline一起使用)--实现实时预览
        inline: true, // 可以单独使用 --实现实时预览
        host: '0.0.0.0',
        port: 8080,
        // historyApiFallback: true,
        contentBase: path.resolve(__dirname, '../dist') // 配置devserver http服务器可访问文件
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['eslint-loader'],
                exclude: /node_modules/,
                enforce: 'pre'
            },
            {
                test: /\.js$/,
                use: [{
                    loader: 'babel-loader'
                }],
                exclude: /node_modules/
            },
            {
                test: /\.(css|less)$/,
                use: [
                    'style-loader',
                    'css-loader',
                    {
                        loader: 'less-loader',
                        options: {
                            javascriptEnabled: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html'),
            filename: 'index.html'
        })
    ]
};

(10)加载图片配置

  1. 在页面里加入一张图片:


    引入图片只能用import才能使用别名路径asset
  2. 发现编译/打包后报错:


    因为没有loader编译img
  3. 上网查找资料后,使用的loader为:file-loader或者url-loader。
    对比其特点:
  • file-loader:将文件发送到输出文件夹,并返回(相对)URL
    (1)编译或者打包都是原大小;
    (2)后期单独写压缩配置。
  • url-loader:像 file loader 一样工作,但如果文件小于限制,可以返回 data URL
    (1)小于limit会进行base64的转码,编译或者打包都会进行压缩;
    (2)大于limit则callback会默认使用file-loader进行编译,因此大于limit的图片还是要自行进行压缩配置;
    (3)若使用url-loader,则为了防止file-loader压缩后的图片小于limit就被进行base64的转码,只能将limit设置为很小(如1kb,或者更小),因此也没什么作用,就直接使用file-loader就好了。

因此,经过权衡,选择file-loader进行配置;现将两个配置文件配置相同,如下:

{
   test: /\.(png|svg|jpe?g|gif)$/I,
      use: [
        {
            loader: 'file-loader'
        }
      ]
}
  1. 打包后发现不会打包在js文件里,直接和index.html同级,并且还有hash值:


    image.png
  2. 想着将图片也打包到单独的文件夹images里,pro做如下配置,并且作区分(development配置无哈希值,prod配置有哈希值):
{
   test: /\.(png|svg|jpe?g|gif)$/I,
   use: [{
          loader: 'file-loader',
          options: {
               outputPath: 'public/images/',
               name: '[name].[hash:8].[ext]'  // development配置:'[name].[ext]'
         }
   }]
}

打包结果:


image.png

(10)压缩图片

  1. 使用image-webpack-loader进行压缩;
  2. 安装nom i -D image-webpack-loader
  3. 在production文件里配置:
{
   test: /\.(png|svg|jpe?g|gif)$/I,
   use: [
        {
           loader: 'file-loader',
           options: {
                 outputPath: 'public/images/',
                 name: '[name].[hash:8].[ext]'
           }
         },
         {
           loader: 'image-webpack-loader' // 对图片的压缩使用相应的默认配置
         }
        ]
}
  1. 加载顺序为:先对图片进行压缩,再通过file-loader编译输出。

(11)加载字体配置

  1. 和图片都使用file-loader;
  2. 将下载好的字体文件放在/assets/font/文件下,然后在less文件里他们应该在最前面定义, 这样浏览器就可以优先选择它们。
// 引入特殊字体库
@font-face {
    font-family: myFont; 
    src: url(assets/font/font.ttf); // 引入几个打包几个
}
... // 其他class
  1. 字体设置:后面样式文件里直接使用font-family: myFont;即可生效;
  2. 目前练习尝试只引入了一种,配置如下:
// production的配置
{
   test: /\.(woff|woff2|eot|ttf|otf)$/,
      use: [
         {
            loader: 'file-loader',
            options: {
                outputPath: 'public/font/',
                name: '[name].[hash:8].[ext]' // development配置:'[name].[ext]'
            }
         }
      ]
}
  1. 后面需要考虑支持多种浏览器的兼容,就需要考虑4种字体格式,我项目里只引入了三种,如下:
// 引入特殊字体库
@font-face {
    font-family: myFont;
    src: 
           url(assets/font/font.woff2) format('woff2'), // 项目中没用到
           url(assets/font/font.woff) format('woff'),
           url(assets/font/font.eot) format('embedded-opentype'),
           url(assets/font/font.ttf) format('truetype');
}

(12)添加css Modules样式引入

  1. 方法一(没有做到模块化)
    引入:import './index.less';
    html:<div className='com1-wrapper'></div>
    注意:webpack不需要配置,样式就可以生效。

  2. 方法二(模块化):
    引入:import styles from './index.less';
    html:<div className={styles['com1-wrapper']}></div>
    注意:需要对webpack进行配置,并只对本地文件进行添加css modules,而对node_modules以及antd样式不需要进行css modules添加,因此需要写两遍css配置,若只写对本地css的处理,则会对antd的样式引入报错,配置如下:

{
  test: /\.(css|less)$/,
  exclude: /node_modules/,                 // 不包含
  use: [
       'style-loader',
        {
           loader: 'css-loader',
           options: {
                 modules: true,
                 localIdentName: '[name]_[local]_[hash:8]'
           }
        },
        {
           loader: 'less-loader',
            options: {
                 javascriptEnabled: true
             }
        }
  ]
},
{
  test: /\.(css|less)$/,
  include: /node_modules/,                  // 包含
  use: [
       'style-loader',
       'css-loader',
       {
          loader: 'less-loader',
          options: {
                 javascriptEnabled: true
          }
       }
   ]
}

解说:
(1)如果没有添加localIdentName: '[name]_[local]_[hash:8],则编译结果如下:


(2)添加之后:编译结果如下:
[name]:less文件名
[local]:className样式名


ok~~css Modules添加完成。

(13)添加浏览器兼容前缀

  1. 安装npm i -D postcss-loader,配置webpack,必须写在less-loader之后,因为必须要将less的语法转为postcss能够识别的语法,后面的前缀样式才能生效。
  1. 说明配置postcss之后,必须要有config文件,因此创建postcss.config.js并进行简单配置:
    nom i -D postcss-preset-env
module.exports = {
    plugins: {
        'postcss-preset-env': {
            autoprefixer: {},
            stage: 3
        }
    }
};
  1. 还必须在 package.json里或者创建.browserslistrc文件进行配置,主要是对浏览器和Node.js版本的支持配置,不懂可参考https://www.npmjs.com/package/browserslist
"browserslist": [
    "> 1% in CN",
    "last 4 versions",
    "Firefox ESR",
    "not ie < 9"
]
  1. 然后重新启动项目css3前缀配置生效,打包构建也成功。


遗留问题(发现):好像用ie打开项目,页面有报错,后面再进行排查吧!

ok~~基本脚手架配置就到这里,后面会对配置进行优化,如:js、css文件压缩,以及对第三方库进行分包打包。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容