webpack的基本配置之Loader篇

1,256 阅读6分钟

什么是webpack

webpack is a module bundler【webpack是一个模块打包工具】

提升Webpack打包速度的方法

  1. nodejs的版本尽量新
  2. webpack的版本尽量新
  • 因为高版本的webpack会利用node新版本中的一些特性来提高打包速度

创建项目,并进行简单的webpack配置

初始化项目

npm init 
// 不会询问配置项的信息,自动选择默认的配置
npm init -y 

--save 与 --save-dev (-D) 的区别

When installing a package that will be bundled into your production bundle, you should use npm install --save. If you're installing a package for development purposes (e.g. a linter, testing libraries, etc.) then you should use npm install --save-dev.

安装webpack

  1. 全局安装(不建议这么做)
  • 全局安装webpack的问题:

如果有两个项目,一个项目是通过webpack3进行打包的,另一个项目是通过webpack4打包的,全局安装的webpack只能打包其中的一个项目。

npm install webpack webpack-cli -g  
npm uninstall webpack webpack-cli -g 
// 其实安装webpack-cli的时候 webpack也一起安装好了
// webpack-cli使我们能够在控制台使用 webpack 这样的命令
  1. 在项目中安装
npm install webapck webpack-cli --save-dev
等价于
npm install webapck webpack-cli -D

//安装指定版本的webpack
npm install webapck@4.16.5 webpack-cli -D
npm install webpack@4.43.0 webpack-cli@3.3.12  -D
// 查看项目中安装的webpack版本
// 利用node的模块 npx,npx是在当前项目的node
   npx webpack -v
// 如果直接使用webpack -v 是去全局环境中寻找webpack

//查看webpack的信息
  npx info webpack 

webpack的配置

  1. 如果项目中没有webpack.config.js这个配置文件,webpack会用默认的配置文件(工具中内置了这个文件)打包
  2. webpack默认只会识别webpack.config.js这个名称的配置文件,如果想以其他名字的文件作为配置文件,可以用下面的方法
//以mywebpackconfig.js为配置文件进行打包
npx webpack --config mywebpackconfig.js
  1. webpack.config.js
//node的模块
const path = require('path')

module.exports = {
  //打包的模式 如果不配置会有一个警告
  mode: 'production',
  // 打包出的代码会被压缩,如果不写mode这个属性默认是production
  // mode: 'development'  打包出的代码不会被压缩,并且会带有注释
  // mode: 'production'  打包出的代码会被压缩,并且会带有注释
  
  //入口文件
  entry: {
  	main: './src/index.js' 
  },
  //等价于
  entry: './index.js' 
  
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist') //如果不写path这个配置项,默认也是这个path: path.resolve(__dirname, 'dist')
    //__dirname表示webpack.config.js文件所在的路径
    //假设webpack.config.js在根目录下
    //那么path: path.resolve(__dirname, 'dist')表示根目录下dist文件夹下的bundle.js文件
  },  
  
  // 配置loader的地方
  module: {
  	rules: [{
  	  test: /\.(png|jpg|gif)$/,
  	  use: {
  	    loader: 'url-loader',
  	    options: {
  	    // placeholder 占位符
  	    name: '[name].[ext]',
  	    outputPath: 'images/',
  	    limit: 2048
  	    }
  	  }
  	}, {
  		test: /\.css$/,
  		use: [
  		'style-loader',
  		{
  			loader: 'css-loader',
  			options: {
  				importLoaders: 2,
  				modules: true
  			}
  		},
  		'sass-loader',
  		'postcss-loader']
  	}]
  }
}

配置package.json中的scripts

  • 如果没有在package.json文件中设置scripts的相关内容,执行webapck index.js会去全局寻找webpack,如果想要使用项目中的 webpack 进行打包就需要执行命令npx webpack

  • 配置package.json中的scripts,下面是package.json的内容

  "scripts": {
    "bundle": "webpack"
  }

配置了package.json之后就可以使用npm run bundle执行编译了,这个时候默认会先在项目中寻找webpack这个指令

打包的入口和出口

entry

  1. 一般配置一个入口文件
entry: './index.js'

等价于

entry: {
  main: './src/index.js' //对应Chunk Names
}
  1. 如果想把'./src/index.js'的文件反复打包两次生成两个文件
  entry: {
    main: './src/index.js',
    sub: './src/index.js'
  },

output

  1. 一般配置,对应entry中配置一个入口文件
  output: {
    // publicPath: 'http://cnd.com/cn',
    // filename: '[name].js',
    filename: 'bundle.js', //如果不配置此项,默认打包的文件名是main.js
    path: path.resolve(__dirname, 'dist') // __dirname指webpack.config.js文件当前路径
  }
  1. 对应多入口的配置

这个时候打包生成的文件不能固定一个唯一的名字,应该通过某种规则,自动生成名字

  output: {
    filename: '[name].js',
    // filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist') // __dirname指webpack.config.js文件当前路径
  }
  1. 给打包后的文件增加域名:publicPath
  output: {
    publicPath: 'http://cnd.com/cn',
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist') // __dirname指webpack.config.js文件当前路径
  }

执行 npm run bundle 命令控制台输入的内容

AssetSizeChunksChunk Names
bundle.js70.4 KiB0main
  • Asset:bundle.js 表示打包出一个名为bundle.js的文件
  • Size:70.4 KiB 表示打包出来的文件名字的大小
  • Chunks:0 表示打包出的文件的id,有时候在做复杂打包的时候会打包出多个文件,每个文件都会有一个自己的id,chunks会包含和该文件有关的其他文件的id
  • Chunk Names:main, Chunks Name和Chunks对应,为什么是main呢,因为webpack.config.js中的配置

webpack-cli 的作用

使我们能够在命令行执行webpack等一系列命令(the tool used to run webpack on the command line)

Loader

处理图片的Loader:file-loader、url-loader

file-loader

1.首先安装file-loader

npm install file-loader -D
  1. file-loader打包的步骤

首先把对应的文件移动到dist目录下,然后返回一个变量给引用了该文件的地方。

  1. 配置file-loader
{
    test:/\.(jpg|png|gif)$/,
    use:{
        loader:'file-loader',
        options:{
            //placeholder 占位符
            name:'[name].[ext]',
            outputPath:'images/'
        }
    }
}

url-loader

url-loader和file-loader的功能非常相似,url-loader不仅能做file-loader能做的事情,而且还能

file-loader和url-loader打包图片的方式的区别

  1. 如果不做特殊配置, url-loader会把图片转化成base64的文件,直接打包在js文件中。
    • 好处:减少了请求图片的http请求
    • 缺点:如果图片很大,会导致打包出来的js很大,加载js的时间会变长
  2. file-loader会把图片单独打包成一个文件输出

url-loader的使用的最佳实践

如果图片比较小,那么就将这个图片以base64的形式打包到js文件中;

如果图片很大,那么就像图片单独打包到一个目录下。

  1. 安装url-loader
npm install url-loader -D
  1. 配置url-loader
{
    test:/\.(jpg|png|gif)$/,
    use:{
        loader:'url-loader',
        options:{
            //placeholder 占位符
            name:'[name].[ext]',
            outputPath:'images/',
            limit:2048 //如果图片大小大于2048【2kb】字节的话,那就像file-loader下被打包到dist/images下,
            //否则会被打包成Base64的字符串放在bundle.js下
        }
    }
}

处理样式文件的Loader

style-loader

  1. 安装
npm install style-loader -D
  1. 用途

将样式文件挂载到页面

  1. 配置style-loader
{
    test:'/\.css$/',
    use:{
        loader: 'style-loader'
    }
}

css-loader

  1. 安装
npm install css-loader -D
  1. 用途

将多个样式文件合并成一个样式文件

  1. 配置
{
    test:'/\.css$/',
    use:['style-loader','css-loader']
}

sass-loader

  1. 安装:sass-loader要安装两个模块
npm install  sass-loader node-sass  -D
  1. 用途

解析sass文件

3.配置

{
    test:'/\.css$/',
    use:['style-loader','css-loader','sass-loader']
}
  • tips:sass-loader版本过高会导致编译失败,解决办法
npm install  sass-loader@6.x --save-dev

style-loader 和 css-loader、sass-loader的关系

  • loader的执行顺势的从下到上,从右到左
  • sass-loader首先将sass代码翻译成css代码
  • css-loader分析多个css的关系,最终把多个css合并成一个css
  • style-loader将css-loader生成的文件挂载到页面的head部分

postcss-loader

  1. 安装
npm install  postcss-loader  -D
  1. 用途

为css自动增加厂商前缀

  1. 安装autoprefixer插件
npm install autoprefixer -D 
  • 根目录下创建postcss.config.js文件,文件中使用autoprefixer插件
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}
  1. 配置
{
    test:'/\.css$/',
    use:['style-loader','css-loader','sass-loader','postcss-loader']
}
  • 如果配置完成,编译之后的文件还是没有厂商前缀,可能是因为新版本的postcss-loader默认的浏览器版本比较高,可以在跟目录下创建.browserslistrc文件设置如下内容:
> 1%
last 2 versions
not ie <= 11
Android >= 4.0
iOS >= 8

模块化的css

  1. 开启方式 将css-loader的options.modules设置为true
{
    test:'/\.css$/',
    use:[
    'style-loader',
    {
        loader:'css-loader',
        options:{
            modules:true    //开启css模块化
        }
    }
    ]
}
  1. 使用方式
import focus from './images/focus.png'
import style from './index.scss'
//通过style.classname引用css
var img = new Image()
img.src = focus
img.classList.add(style.newavatar)

css有关的loader配置的具体内容

{
    test:'/\.css$/',
    use:['style-loader',
      {
        loader:'css-loader',
        options:{
          importLoader:2, //假设我们的js文件中引入index.scss文件中
                          //index.scss又通过 @import'./focus.scss' 引入其他scss文件,
                          //这个配置保证引入的scss也会从下到上执行loader
                          //不过目前新版本的webpack已经不需要这个配置,默认就支持这个功能
          modules:true    //开启css模块化
      }
    }'sass-loader']
}

打包字体文件的loader

字体文件的使用

  1. 登录iconfont的网站
  2. 选取自己想使用的图标加入购物车
  3. 点击购物车将图标库加入项目
  4. 下载字体文件
  5. 将下载的字体文件放在项目的资源目录下
  6. 使用字体文件

打包字体文件使用file-loader,配置如下

{
    test: /\.(eot|ttf|svg)$/,
    use:{
        loader:'file-loader'
    }
}

Entry 和 Output

  entry: {
    main: './src/index.js',
    sub: './src/index.js'
  }
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  }