webpack4.0 基础知识

1. webpack基础配置

webpack4.0必须安装webpack和wabpck-cli

webpack可以0配置,它默认支持js模块化,因此可以使用commonjs语法

1.基础配置项

配置文件的默认名为webpack.config.js或者webpackfile.js,(自定义名称的话可再命令中添加config参数)

  • entry(入口)
    Sring | Array | Object
  • output
output:{
    filename: 'bundle.js',   // 打包后的文件名
    path: path.resolve(__dirname, 'dist')   // 路径必须是绝对路径,(先引入path模块)
  }
  • module
  • mode
    • development/production

2.webpack打包出的文件解析

3.Html插件

  • webpack-dev-server //模拟线上环境(不会真实打包,在内存中打包),在webpack.config.js文件中的对应字段为devServer
devServer: {
    port: 3000,
    progress: true,  //  打包进度条
    contentBase: './dist',  //根地址对应路径
    compress: true  // 是否启用gzip压缩
  },
  • html-webpack-plugin // html相关的插件
plugins: [  //放着所有的webpack插件
   new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html',
      minify: {
        removeAttributeQuotes: true,
        collapseWhitespace: true
      },
      hash: true
    })
]

4.模块处理(或者.vue,.js等等文件)

主要用于处理非js模块(es6 to es5),需要在module中配置相应处理规则和加载器,以下,先以样式处理为例子

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

style-loader会把样式以<style>标签的形式插入到head标签中,如果要将样式单独抽离成css文件,就需要用到插件‘mini-css-extract-plugin’了

let MiniCssExtractPlugin = require('mini-css-extract-plugin');   //引入插件(得先安装);
module: {
    rules: [
      {
        test: /\.(sc|c)ss$/,  // sass-loader node-sass, less less-loader, stylus stylus-loader
        use: [
          MiniCssExtractPlugin.loader,  //此处就不用了‘style-loader’了
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  },
plugins: [
    new MiniCssExtractPlugin({
      filename: 'main.css'
    })
  ]

如果用到css3的新功能,那么就需要加前缀,首先装包 postcss-loader, autoprefixer,然后需要配置postcss的config文件(postcss.config.js)

// postcss.config.js文件
 module.exports = {
  plugins: [require('autoprefixer')]
}
//webpack.config.js文件
module: {
    rules: [
      {
        test: /\.(sc|c)ss$/,  // sass-loader node-sass, less less-loader, stylus stylus-loader
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',  //先预处理css,得出结果后才用css-loader
          'sass-loader'
        ]
      }
    ]
  },

如果要压缩css,首先,配置文件中,mode需设置为“production”,然后在webpack配置文件中添加字段“optimization”,用插件optimize-css-assets-plugin压缩CSS

optimization: {
    minimizer: [
      new OptimizeCss(),
      new TerserJs({
        cache: true,
        sourceMap: true
      })
    ]
  }

处理js模块(es6 -> es5),首先安装模块加载器‘babel-loader’,然后安装babel核心模块“@babel/core”,最后安装转换规则(es6,es7,提案阶段...)模块,这里我们使用“@babel/preset-env”

module: {
    rules: [
      {
        test: /\.(sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          "sass-loader"
        ]
      },
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: ["@babel/plugin-proposal-class-properties"]   //这个插件是为了转换es7的class语法
          }
        }
      }
    ]
 },

babel默认不转化新的API,需要“@babel/plugin-transform-runtime”来转化(但是比如“foobar”.includes(“foo”),Object.assign等就需要安装@babel/polyfill),这个包是开发依赖,上线也需要支持新的语法,因此还需要“@babel/runtime”,将其添加至plugins。同时,转化js应该避开node_modules
文件夹

{
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: [
              ["@babel/plugin-proposal-class-properties"],
              ["@babel/plugin-transform-runtime"]
            ]
          }
        },
        include: path.resolve('dist'),
        exclude: /node_modules/
      }

4.配置eslint

eslint是js的语法校验规则,可以去官网demo处下载eslint.json文件,根据自己的需求添加校验规则。

loader的执行顺序是右向左,下向上,因此匹配到js是,先校验,然后才进行转化语法,压缩等操作,use中有字段“enforce”来指定loader执行顺序,如下

//为了灵活配置(比如后期可能不需要eslint了),因此将eslint规则单独放开
  {
        test: /\.js$/,
        enforce: 'pre'   //pre,post(此处有坑,eslint-loader文档中写的是和“loader”字段同级,经实测,可放在这里,也可放在loader的options中)
        use: [
          {
            loader: 'eslint-loader' 
          }
        ]
      },
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
            plugins: [
              ["@babel/plugin-proposal-class-properties"],
              ["@babel/plugin-transform-runtime"]
            ]
          }
        },
        include: path.resolve("src"),
        exclude: /node_modules/
      }

5.第三方模块的使用

我们以jquery为例

//index.js
import $ from "jquery"
console.log($)
//在做传统项目时,如果引入了jquery,那么在全局都可以使用(绑定在了window上)
//那么我们打印一下“window.$”
console.log(window.$)

005236.png

window.$是undefined
此时,我们可以使用“expose-loader”,暴露全局的loader,这是内联loader。(loader类型,pre-前置,post-后置,normal-普通loader,内联loader)

import $ from "expose-loader?$!jquery";
console.log($);

console.log(window.$);
005854.png

当然,也可以写成普通loader的方式

 module: {
    rules: [
      {
        test: require.resolve("jquery"),
        use: "expose-loader?$"
      }
]

还可以不在每个页面引入,直接把jquery集成到webpack配置中

首先引入webpack,然后调用webpack自带的providePlugin

new webpack.ProvidePlugin({
    $: "jquery"
  })

可是打包之后,发现bundle.js文件过大,将jquery也打包进去了,这时可以将JS引用方式改为CDN引入。
然后在webpack配置文件中添加externals字段

externals: {
    jquery: "jQuery"
  },

webpack在打包时,会分析每个包的依赖,像jquery这种不依赖任何包的包,解析是没有必要的,它会拖慢打包速度,这是,可以在module中添加字段“noParse”

module: {
 npParse: /jquery/  //不去解析jquery的依赖库
}

6.webpack打包图片

常规项目中我们要使用image,一般有三种方式:

//1.js导入
var Img = new Image(); 
Img.src = './image.png'; 
document.body.appendChild(Img);
//2.css中元素背景
body{
  background: url('./image.png') 100%/center;
}
//3.html中
<img src="./image.png">

在webpack中,如果以JS方式引用图片,得先在webpack配置文件中加上“file-loader”)

//webpack.config.js
...
modlue: {
  rules: [
    {
        test: /\.(jpg|png|gif)$/,
        use: 'url-loader'
      }
  ]
}
...
//1.js导入
let imgFile = require('./image.png')//以模块的方式导入
var Img = new Image(); 
Img.src = './image.png';  //在webpack项目中,打包后以这种相对路径的方式引用图片资源是不行的,必须先以模块的方式导入(以上require)
document.body.appendChild(Img);
//2.css中引入
//因为引入了css-loade,在css文件中,“background:url('./logo.png')”会被自动转化为“background:url(require('./logo.png'))”,因此,不用做特殊处理
//3.在html中引入,同理,打包后的文件不能从“./”目录找到相应的资源,这时可以使用插件“html-withimg-loader”
//webpack.config.js
module: {
  rules: [
    {
      test: /\.html$/,
      use: 'html-withimg-loader'
    }
  ]
}

如果图片较小时,为了减少http请求,可以将图片转为base64,要用到加载器“url-loader”

rules: [
  {
    test: /\.(jpg|png|gif)$/,
    // 可以给一个限制,图片大小小于某个值时,转为base64,否则会自动使用“flie-loader”将文件拷贝至生产目录。(如果想让img文件都存放在特定的文件夹中,可以指定“name”参数)
    use: {
       loader:  'url-loader',
        options: {
          limit: 200*1024,
          name: image/[name].[hash:5].[ext]
        }
    }
  }
]
// 同理,生成的css类文件也可以放在指定文件夹中,只需在文件名前加路径
plugins: [  //放着所有的webpack插件
    ....
    new MiniCssExtractPlugin({
      filename: 'css/main.css'
    })
  ]

在浏览器中运行


browser1.png

6.文件分块打包

以上,在正式环境中,如果img,js,css等资源都要放到cdn服务器上,那么像“image/logo1.png”就得变成“https://xxx.xxxx.xx/image/logo1.png”这种形式。此时,可以在webpack配置文件的output中添加publicPath字段来指定域名

output: {
    filename: 'bundle.[hash:5].js', //打包后的文件名
    path: path.resolve(__dirname, 'dist'),
    publicPath: 'http://www.baidu.com'
  },
browser2.png

如果只有某种文件上cdn,比如图片,可以将publicPath写到对应处理规则中,但output中的对应字段得删掉

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

推荐阅读更多精彩内容

  • 全局安装webpack 全局安装webpack会有个问题,就是当你有两个项目依赖于不同版本的webpack,就会有...
    説好的妹紙呢阅读 1,789评论 0 11
  • webpack使用学习 本分享学习借鉴webpack中文官网,官网链接(中文文档):https://www.web...
    腿毛怪丶叔叔阅读 862评论 0 5
  • 写在开头 先说说为什么要写这篇文章, 最初的原因是组里的小朋友们看了webpack文档后, 表情都是这样的: (摘...
    Lefter阅读 5,258评论 4 31
  • 初始化项目 进入一个文件夹作为项目的根目录 npm init 新建src, dist目录,package.json...
    love_program阅读 1,223评论 0 4
  • 小布一心盼着下课,以便在黑暗角落里和隔壁班的女生打两句闲话,开几句不很雅观的玩笑。 但是第一节自习下课铃响的时候,...
    行走的M阅读 305评论 0 0