Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

从零配置webpack 4+react脚手架(三) #6

Open
vortesnail opened this issue Oct 13, 2019 · 0 comments
Open

从零配置webpack 4+react脚手架(三) #6

vortesnail opened this issue Oct 13, 2019 · 0 comments
Labels

Comments

@vortesnail
Copy link
Owner

前言:

这一节我们将在脚手架中引入CSS,SASS,LESS,并且实现代码压缩,以及PostCSS的使用。

先让CSS跑起来

新建CSS文件

在我们的 /src 目录下,新建一个文件名为 app.css ,并输入以下代码:

.App {
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightcoral;
}

h1 {
  font-size: 16px;
  color: #fff;
}

在app.js中引入css

打开 /src/app.js ,添加以下代码:

import './app.css';

配置loader

wbpack只能编译js文件,css文件是无法被识别并编译的,我们需要loader加载器来进行预处理。
首先安装 style-loader 和 css-loader :

npm install --save-dev style-loader css-loader  

注:

  • 遇到后缀为.css的文件,webpack先用css-loader加载器去解析这个文件,遇到“@import”等语句就将相应样式文件引入(所以如果没有css-loader,就没法解析这类语句),最后计算完的css,将会使用style-loader生成一个内容为最终解析完的css代码的style标签,放到head标签里。
  • loader是有顺序的,webpack肯定是先将所有css模块依赖解析完得到计算结果再创建style标签。因此应该把style-loader放在css-loader的前面(webpack loader的执行顺序是从右到左)。

配置module.export.rules

在webpack.prod.config.js中配置:

const merge = require('webpack-merge');
const common = require('./webpack.common.config.js');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = merge(common, {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 
          'style-loader', 
          'css-loader' 
        ]
      }
    ]
  },
  //...
});

现在,执行一下 npm run build ,打开页面,发现样式生效。你再打开控制台看Elements,发现style样式已经插入到了****内。

打包出CSS独立文件

我们可以看到上面,style样式是通过style-loader预处理,插入到了head标签内,但是我们平常写样式的时候,一定是通过引入外部css文件进行样式引入的,那我们怎么做呢?使用插件 mini-css-extract-plugin :

安装 mini-css-extract-plugin

npm install --save-dev mini-css-extract-plugin

引入 mini-css-extract-plugin

webpack.prod.config.js 中引入:

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

配置plugin

module.exports = merge(common, {
  plugins: [
    //...
    new MiniCssExtractPlugin({
      filename: 'css/[name].[hash].css',
      chunkFilename: 'css/[id].[hash].css',
    }),
  ]
});

修改loader

module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 
          MiniCssExtractPlugin.loader,
          'css-loader' 
        ]
      }
    ]
  },

现在你的webpack.prod.config.js应该是下面这样:

const merge = require('webpack-merge');
const common = require('./webpack.common.config.js');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = merge(common, {
  mode: 'production',
  output: {
    filename: 'js/[name].[chunkhash:8].bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 
          MiniCssExtractPlugin.loader,
          'css-loader' 
        ]
      }
    ]
  },
  optimization: {
    minimizer: [new UglifyJsPlugin()],
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      cacheGroups: {
        framework: {
          priority: 100,
          test: "framework",
          name: "framework",
          enforce: true
        },
        vendors: {
          priority: -10,
          test: /node_modules/,
          name: "vendor",
          enforce: true,
        },
      }
    }
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'public/index.html',
      inject: 'body',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
      },
    }),
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: 'css/[name].[hash].css',
      chunkFilename: 'css/[id].[hash].css',
    }),
  ]
});

我们再执行一下 npm run build ,查看dist目录,你会发现css文件已经被单独打包出来了。

压缩打包出的CSS文件

我们打开dist目录下打包生成的css文件,你会发现他和我们写的是一模一样的,这意味着该代码没有被压缩,使用插件optimize-css-assets-webpack-plugin来做这项工作。

安装optimize-css-assets-webpack-plugin

npm install --save-dev optimize-css-assets-webpack-plugin

引入optimize-css-assets-webpack-plugin

webpack.prod.config.js 中引入:

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

配置minimizer参数

optimization: {
  minimizer: [
    new UglifyJsPlugin(),
    new OptimizeCssAssetsPlugin({
      assetNameRegExp:/\.css$/g,
      cssProcessor:require("cssnano"),
      cssProcessorPluginOptions:{
        preset:['default', { discardComments: { removeAll:true } }]
      },
      canPrint:true
    })
  ],
  //...
}
参数 意义
assetNameRegExp 正则表达式,用于匹配需要优化或者压缩的资源名。默认值是
/.css$/g
cssProcessor 用于压缩和优化CSS 的处理器,默认是 cssnano.
cssProcessorPluginOptions 传递给cssProcessor的插件选项,默认为{}
canPrint 表示插件能够在console中打印信息,默认值是true
discardComments 去除注释

另外,这段配置也是可以放到 plugins 这个属性下进行配置的。
配置完成,执行 npm run build ,查看dist目录下打包出的css文件是不是代码被压缩了!

接着让Less或Sass飞起来

我们写项目的时候没几个人会去写css吧?sass或less对于工作效率的提高是肉眼可见的,但是我们webpack也同样无法理解这种编写方式,那就需要配置loader做预处理,将其转换为css。

安装less-loader,sass-loader

npm install --save-dev less less-loader node-sass sass-loader

配置loader

webpack.prod.config.js 中的 module.rules 内增加两个对象:

module: {
    rules: [
      //...
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader'
        ]
      },
      {
        test: /\.(sass|scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader'
        ]
      },
    ]
  },

我们将 src 目录下的 app.css 改为 app.less 或 app.sass ,在里面改为以下代码:

.App {
  height: 200px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightcoral;
  h1 {
    font-size: 16px;
    color: #fff;
  }
}

然后修改 app.js 中的引入 import 'app.less' 或 import 'app.sass' 

执行 npm run build 看看是否把less文件或sass文件打包成了dist目录下的css文件

使用PostCSS

postcss 一种对css编译的工具,类似babel对js的处理,常见的功能如:
1 . 使用下一代css语法
2 . 自动补全浏览器前缀
3 . 自动把px代为转换成rem
4 . css 代码压缩等等
postcss 只是一个工具,本身不会对css一顿操作,它通过插件实现功能,autoprefixer 就是其一。

安装postcss

npm install postcss postcss-loader --save-dev

安装postcss某个插件,以Autoprefixer举例

npm install autoprefixer --save-dev

配置postcss.config.js

根目录新建postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')({ browsers: ['last 5 version', '>1%', 'ie >=8'] })
  ]
};

设置loader

module.exports = merge(common, {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      },
    ]
  },
  //...
});

执行 npm run build 可以,浏览器打开dist目录下的index.html,控制台看css样式,加上了浏览器前缀:
image.png

我们可以复制一份webpack.prod.config.js中关于rules的配置到webpck.dev.config.js,修改第一个为style-loader,因为我们在开发环境下没必要打包单独文件。

以下是webpck.dev.config.js部分配置

module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 
          'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'less-loader'
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          'style-loader',
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      },
    ]
  },

现在执行 npm run start 来启动开发环境。

到此为止,我们已经基本搭起了一个简单的react脚手架,下一节,我们还需要再进行相关配置的优化!很重要!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant