龙空技术网

深入剖析webpack——webpack 基础

iceman的碎碎念 249

前言:

而今大家对“cssloader和styleloader区别”大概比较关怀,同学们都想要剖析一些“cssloader和styleloader区别”的相关文章。那么小编也在网上收集了一些对于“cssloader和styleloader区别””的相关内容,希望朋友们能喜欢,朋友们一起来学习一下吧!

现在做前端开发用 webpack 很多,之前有深入研究过,并且做了很多相关笔记。一直想着整理出来,刚好同事这两天有问到我 webpack 相关的问题,趁着这个机会我自己也好好梳理一下。

准备写 webpack 的系列文章,从基础、优化到原理。

最基本使用安装 webpack 依赖:

npm install webpack@4 webpack-cli@3 -D

注意: 由于我们公司当前所有项目都未升级到 webpack5.x,所以这系列文章基于 webpack4.x 来写,后续单独写 webpack5.x 相关的。

创建 webpack.config.js

如果不创建 webpack.config.js,webpack 会使用默认的配置的文件,但是默认的配置文件功能很弱,这里就不再讲了。项目开发过程中都会自己写配置文件。

配置文件的名字也可以不叫 webpack.config.js,只需要在执行 webpack 命令的时候声明即可:

npx webpack --config 你自己的定义的文件名

注意:正常情况下,我们都不会去改配置文件的名称。

entry、output

在项目目录下建一个 src 目录,在 src 目录下创建 index.js、test1.js

test1.js

exports.name = 'iceman';

index.js

const test1 = require('./test1');console.log(test1.name);

写 webpack.config.js 中的配置的时候需要知道 webpacknode 写出来的,所以要遵循 node 的语法。

module.exports = {  entry: './src/index.js',  output: {    filename: 'main.js',    path: path.resolve(__dirname, 'dist'),  }}

entry 为入口文件。

output 为输出的配置:

filename:打包后的文件名,可以给 filename 加上 hash ,每次打包后的文件名就不一样了,可以防止缓存。filename: 'main.[hash].js',如果觉得 hash 太长,可以设置长度 filename: 'main.[hash:8].js'path:打包后的文件的输出路径,这里的路径必须是一个绝对路径,可以使用 nodepath 模块中的 resolve 生成绝对路径。mode

做完以上配置之后,输入打包命令:

npx webpack

能打包,但是输出警告信息:

这段警告告诉我们没有设置 modewebpack 会默认使用 production。mode 的设置可以在控制台输入打包命令的时候添加:

npx webpack --mode=production

也可以在配置文件中指定:

注意:这里只是演示,一般不会直接写死 “production” 、“development”,都是通过控制台输入打包命令的时候设置变量,然后动态判断。

#plugins

我们现在将一个 HTML 文件也打包进 dist 文件中,作为我们项目的入口 HTML。

在这个 HTML 中还要将 dist 中的 JavaScript 入口文件引进去,这个操作肯定不可能每次都手动的操作。

这时候就要用到 plugins 了,plugins 是个数组,里面放所有的 webpack 插件。拷贝 HTML 可以用 html-webpack-plugin 插件。

plugins: [  new HtmlWebpackPlugin({    template: './src/index.html',    filename: 'index.html'  }),]

这个插件中的 templatefilename 这两个参数很好理解,就是需要拷贝的模板和输出的文件名。输出到 dist 中的 HTML 如下:

输出的 HTML 文件中,已经自动引入了入口 JavaScript 文件。

该插件还有其他几个参数:

new HtmlWebpackPlugin({  template: "./src/index.html",  filename: "index.html",  minify: {    removeAttributeQuotes: true,    collapseWhitespace: true,  },  hash: true})
minify#removeAttributeQuotes:去除 HTML 中的引号minify#collapseWhitespace:将空行压缩hash:引入 JavaScript 文件加上随机的 url 参数 module

到现在为止,已经将 HTML、JavaScript 都打包了。如果这时候要引入样式文件呢?

如果要打包样式,需要用到样式相关的 loaderloader 写在 modulerules 中。

安装 css-loaderstyle-loader

npm install css-loader style-loader -D
module: {  rules: [    {test: /\.css$/, use: ['style-loader', 'css-loader']}  ]}

loader 的执行顺序是 从右向左

css-loader 的作用是解析 @import 这样的语法,style-loader 的作用是把 css 插入到 head 标签中。

从这里也可以看出,loader 的设计理念是功能单一,一个 loader 只做一件事,然后组合做个 loader。

loader 的写法除了上面的字符串的形式,还可以写成对象的形式,用对象的形式有一个好处就是可以给 loader 加参数:

module: {  rules: [    {      test: /\.css$/,      use: [        {          loader: 'style-loader',          options: {            insertAt: 'top',          }        },        'css-loader'      ]    }  ]}

在 src 下写一个样式文件 test02.css:

body {  background-color: #ddd;}

index.js 中引入:

require('./test02.css');

以上的操作之后,就可以打包 css 文件了。如果要打包 Less,也是一样的思路,加上相应的 loader 即可:

{  test: /\.less$/,  use: ['style-loader', 'css-loader', 'less-loader']}
webpack-dev-server

平时开发过程中,修改了某个 JavaScript 文件,或者某个 css 文件,如果每次都要手动打包一次,然后再手动打开 index.html,那么效率相当低。这一点 webpack 也考虑到了,提供了 webpack-dev-server 给我们使用。

npm install webpack-dev-server

在配置文件中加入相关配置:

devServer: {  port: 8080,  // 显示进度条  progress: true,  // 根目录  contentBase: './dist',  // 是否开启 gzip 压缩  compress: true}
样式处理

走完一遍 最基本的使用 之后,对 webpack 已经不那么陌生了。接下来我们继续学习使用 webpack

在上面讲解 module 的时候,有介绍到样式的处理,介绍了 style-loadercss-loaderless-loader,有了这三个插件,已经能正常的处理样式了。不过还不够,对于样式的处理,还有一些细节。

样式抽取为单独的文件

现在所有的样式都是直接插入到 <head></head> 中。

可以使用 mini-css-extract-plugin 来抽取样式。

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');module.exports = {  plugins: [    new MiniCssExtractPlugin({      filename: 'main.css',    }),  ],}

除了在 plugins 中添加相应的插件之外。还需要将 modulerules 中和样式相关的 style-loader 换成 MiniCssExtractPlugin.loader

自动补齐 CSS3 属性前缀

安装依赖:

npm i postcss-loader autoprefixer@8 -D

注意:在使用中控制台报错,Error: PostCSS plugin autoprefixer requires PostCSS 8. Update PostCSS or downgrade this plugin,提示我们要使用8.x的版本。

postcss-loader 必须放在 css-loader 之前。

根目录下新建 postcss.config.js

module.exports = {  plugins: [require('autoprefixer')],}
压缩 CSS 文件

安装依赖:

npm i optimize-css-assets-webpack-plugin -D

在配置文件中新加 optimization ,就是优化项的意思。

optimization: {    minimizer: [      new OptimizeCssAssetsPlugin(),    ]}

做完以上配置之后,css 文件就会压缩。

既然 CSS 文件可以压缩了,那么 JS 文件是不是也可以压缩呢?

安装依赖:

npm i uglifyjs-webpack-plugin -D
optimization: {  minimizer: [    new UglifyJsPlugin({      cache: true,      parallel: true,      sourceMap: true,    }),  ]}

参数的具体含义以及其他参数可查看文档:。

注意:以上压缩的配置一定是在 mode: 'production' 的情况生效的,在 development 的情况下不会生效。

ES6+编译 ES6

const fn = () => {  console.log('aa');}fn();

这段箭头函数的代码,默认情况下是不会被编译的。需要用 babel

安装依赖

npm i babel-loader @babel/core @babel/preset-env  -D
module: {  rules: [    {      test: /\.js$/,      use: {        loader: 'babel-loader',        options: {          presets: [            '@babel/preset-env',          ],        },      },    }  ]}
编译 decorator

以上的配置无法编译 decorator,需要加额外配置。

function Controller(target) {  console.log(target);}@Controllerclass A {  }
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
module: {  rules: [    {      test: /\.js$/,      use: {        loader: 'babel-loader',        options: {          presets: [            '@babel/preset-env',          ],          "plugins": [             ["@babel/plugin-proposal-decorators", { "legacy": true }],             ["@babel/plugin-proposal-class-properties", { "loose" : true }]          ]        },      },    }  ]}
打包图片

图片一般会以是那种情况出现:

JS 代码中直接使用CSS 中引入img 标签中使用JS、CSS 中使用

安装依赖

npm install file-loader@3 -D

配置文件:

module: {  rules: [    {      test: /\.(png|jpg|gif)&/,      use: {        loader: 'file-loader',      }    }  ]}

JS 中使用:

import st from './st.jpg';const img = new Image();img.src = st;document.body.appendChild(img);

CSS中使用:

body {  background-image: url("./st.jpg");}

注意这里的如果 file-loader 用的不是 3.x 版本的话,编译出来的 css 文件会有问题:

以上两种方式都是使用的 file-loaderfile-loader 的机制是在内部生成一张图片,到build目录下,再把生成的图片的名字返回回来。

还有一个 url-loader,它会将图片 BASE64 编码:

{  test: /\.(png|jpg|gif)$/,  use: {    loader: 'url-loader',    options: {      limit: 10 * 1024,      outputPath: '/img/',    }  }}

outputPath 为图片的输出路径。

当图片小于 limit 的时候会把图片 BASE64 编码,大于 limit 参数的时候还是使用 file-loader 进行拷贝。

注意:BASE64 编码之后,图片的体积会变大三分之一左右,所以对于较大得图片不要用 url-loader,在 options 中设置 limit。

img 标签中使用

在 img 标签中使用图片,需要 html-withimg-loader

安装依赖

npm i html-withimg-loader -D

配置文件

{  test: /\.html$/,  use: 'html-withimg-loader'}

标签: #cssloader和styleloader区别