webpack打包测试_webpack实战第一篇(基础部分)

本文内容强烈建议自己手动敲一遍,建立自己的基础模板,很重要。不扯webpack是干嘛的了,不懂的小伙伴自行百度,也可看下面实践案例。本文内容主要转载于下文,是学习用的,直接上干货。爱前端不爱恋爱:2020年了,再不会webpack敲得代码就不香了(近万字实战)​zhuanlan.zhihu.com基础部分1.1 新建一个项目npm init 安装依赖npm i -D webpack webpack...
摘要由CSDN通过智能技术生成

b0e7702fd1ff25b5089c0d57adbbf270.png

本文内容强烈建议自己手动敲一遍,建立自己的基础模板,很重要。

不扯webpack是干嘛的了,不懂的小伙伴自行百度,也可看下面实践案例。本文内容主要转载于下文,是学习用的,直接上干货。

爱前端不爱恋爱:2020年了,再不会webpack敲得代码就不香了(近万字实战)​zhuanlan.zhihu.com

基础部分

1.1 新建一个项目

npm init 

安装依赖

npm i -D webpack webpack-cli
  • npm i -D 为npm install --save-dev的缩写
  • npm i -S 为npm install --save的缩写

然后我们新建一个文件夹和文件src/main.js,测试一下

main.js 内容

console.log('测试webpack')

webpack 配置内容

  "scripts": {
    "build": "webpack src/main.js"
  },

执行命令测试一下

npm run build

此时如果生成了一个dist文件夹, "scripts": {
"build": "webpack --config build/webpack.config.js"
},并且内部含有main.js说明已经打包成功了

1.2 自定义配置

上一个简单的例子只是webpack自己默认的配置,下面我们要实现更加丰富的自定义配置

新建一个build文件夹,里面新建一个webpack.config.js

// webpack.config.js

const path = require('path');
module.exports = {
    mode:'development', // 开发模式
    entry: path.resolve(__dirname,'../src/main.js'),    // 入口文件
    output: {
        filename: 'output.js',      // 打包后的文件名称
        path: path.resolve(__dirname,'../dist')  // 打包后的目录
    }
} 

更改我们的打包命令

"scripts": {
   "build": "webpack --config build/webpack.config.js"
}

执行 npm run build ,发现dist目录下又新生成了一个文件output.js, 这个js就是我们在浏览器下真正运行的文件。 ps: main.js是第一步生成的,不要误解。

64107c9f75447edb38315c859723e91f.png

1.3 配置html模板

我们要考虑一个问题,js文件打包好了,但是我们不可能每次在html文件中手动引入打包好的js (html模板建立在后面)

这里可能有的朋友会认为我们打包js文件名称不是一直是固定的嘛(output.js)?这样每次就不用改动引入文件名称了呀?实际上我们日常开发中往往会这样配置:

module.exports = {
    // 省略其他配置
    output: {
      filename: '[name].[hash:8].js',      // 打包后的文件名称
      path: path.resolve(__dirname,'../dist')  // 打包后的目录
    }
}

执行npm run build

ff4bea8687c4829bccfc962bfac615a9.png

会发现生成了一个main.9f1e44ba的文件,这个就是我们新的打包方式生成的js文件了。

为了缓存,你会发现打包好的js文件的名称每次都不一样。webpack打包出来的js文件我们需要引入到html中,但是每次我们都手动修改js文件名显得很麻烦,因此我们需要一个插件来帮我们完成这件事情

npm i -D html-webpack-plugin

好了,我们开始新建一个public目录(为了以后放一些其他的资源)和html文件

aa333d7acb9bca446f29cb4dc98a4143.png

webpack配置如下

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode:'development', // 开发模式
    entry: path.resolve(__dirname,'../src/main.js'),    // 入口文件
    output: {
      filename: '[name].[hash:8].js',      // 打包后的文件名称
      path: path.resolve(__dirname,'../dist')  // 打包后的目录
    },
    plugins:[
      new HtmlWebpackPlugin({
        template:path.resolve(__dirname,'../public/index.html')
      })
    ]
}

在dist文件夹下生成了一个html文件和一个js

5b4b3a1e3bda2dff740d9f1c5066ca76.png

a5fd7438b09e50c96f4b04071b5936ea.png

可以发现打包生成的js文件已经被自动引入html文件中

补充1 多入口文件如何进行开发

生成多个 html-webpack-plugin实例来解决这个问题,这里我不在演示。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode:'development', // 开发模式
    entry: {
      main:path.resolve(__dirname,'../src/main.js'),
      header:path.resolve(__dirname,'../src/header.js')
  }, 
    output: {
      filename: '[name].[hash:8].js',      // 打包后的文件名称
      path: path.resolve(__dirname,'../dist')  // 打包后的目录
    },
    plugins:[
      new HtmlWebpackPlugin({
        template:path.resolve(__dirname,'../public/index.html'),
        filename:'index.html',
        chunks:['main'] // 与入口文件对应的模块名
      }),
      new HtmlWebpackPlugin({
        template:path.resolve(__dirname,'../public/header.html'),
        filename:'header.html',
        chunks:['header'] // 与入口文件对应的模块名
      }),
    ]
}

补充2 清理我们的dist目录

每次执行npm run build 会发现dist文件夹里会残留上次打包的文件,如下图所示,这里推荐一个plugin来帮我们在打包输出前清空文件夹 clean-webpack-plugin

2b718dcbaa972659e94845836e085e8c.png
npm i -D clean-webpack-plugin  //安装插件

使用clean-webpack-plugin插件

const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
    // ...省略其他配置
    plugins:[new CleanWebpackPlugin()]
}

这样每次打包我们的dist目录就很干净了,不会遗留之前打包的文件了

9035e19f316de150259f4d489094e829.png

1.4 引入css

我们的入口文件是js,所以我们在入口js中引入我们的css文件

28bb216dd29c20ad6610a70a47dfca63.png
// index.css  
body{
 background: red;
}
// index.less
body{
 color: yellow;
}

同时我们也需要一些loader来解析我们的css文件

npm i -D style-loader css-loader

如果我们使用less来构建样式,则需要多安装两个

npm i -D less less-loader

配置文件如下

// webpack.config.js
module.exports = {
    // ...省略其他配置
    module:{
      rules:[
        {
          test:/.css$/,
          use:['style-loader','css-loader'] // 从右向左解析原则
        },
        {
          test:/.less$/,
          use:['style-loader','css-loader','less-loader'] // 从右向左解析原则
        }
      ]
    }
}

浏览器打开index.html如下

a709f57e92f4bfc4fa0c95a1fcf92a6c.png

我们的css已经生效了

1.4.1 为css添加浏览器前缀

npm i -D postcss-loader autoprefixer

配置如下

// webpack.config.js
module.exports = {
    module:{
        rules:[
            test/.less$/,
            use:['style-loader','css-loader','postcss-loader','less-loader'] // 从右向左解析原则
        ]
    }
}

接下来,我们还需要引入autoprefixer使其生效,这里有两种方式,这里我采用了第二种方式。

1 在项目根目录下创建一个postcss.config.js文件,配置如下:

module.exports = {
    plugins: [require('autoprefixer')]  // 引用该插件即可了
}

2 直接在webpack.config.js里配置

// webpack.config.js
module.exports = {
    //...省略其他配置
    module:{
        rules:[{
            test:/.less$/,
            use:['style-loader','css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require('autoprefixer')]
                }
            },'less-loader'] // 从右向左解析原则
        }]
    }
}

1.4.2 拆分css

这时候我们发现css通过style标签的方式添加到了html文件中,但是如果样式文件很多,全部添加到html中,难免显得混乱。这时候我们想用把css拆分出来用外链的形式引入css文件怎么做呢?这时候我们就需要借助插件来帮助我们

npm i -D mini-css-extract-plugin
webpack 4.0以前,我们通过 extract-text-webpack-plugin插件,把css样式从js文件中提取到单独的css文件中。webpack4.0以后,官方推荐使用 mini-css-extract-plugin插件来打包css文件

配置文件如下:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
  //...省略其他配置
  module:{
        rules:[
          {
            test:/.css$/,
            use:['style-loader',MiniCssExtractPlugin.loader,'css-loader'] // 从右向左解析原则
          },
          {
            test:/.less$/,
            use:['style-loader',MiniCssExtractPlugin.loader,'css-loader',{
                loader:'postcss-loader',
                options:{
                    plugins:[require('autoprefixer')]
                }
            },'less-loader'] // 从右向左解析原则
        }
        ]
  },
  plugins: [
    new MiniCssExtractPlugin({
        filename: "[name].[hash].css",
        chunkFilename: "[id].css",
    })
  ]
}

打包后目录如下所示

38de1dfd990530d54bc4e95941f6e563.png

css文件如图

5d8f82242040729dd04d2e64e4d43d95.png

可见,我们的拆分css文件成功。

补充 拆分多个css

这里需要说的细一点,上面我们所用到的 mini-css-extract-plugin会将所有的css样式合并为一个css文件。如果你想拆分为一一对应的多个css文件,我们需要使用到 extract-text-webpack-plugin,而目前 mini-css-extract-plugin还不支持此功能。我们需要安装@next版本的 extract-text-webpack-plugin
npm i -D extract-text-webpack-plugin@next

这里不再演示

// webpack.config.js
const path = require('path');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
let indexLess = new ExtractTextWebpackPlugin('index.less');
let indexCss = new ExtractTextWebpackPlugin('index.css');
module.exports = {
    module:{
      rules:[
        {
          test:/.css$/,
          use: indexCss.extract({
            use: ['css-loader']
          })
        },
        {
          test:/.less$/,
          use: indexLess.extract({
            use: ['css-loader','less-loader']
          })
        }
      ]
    },
    plugins:[
      indexLess,
      indexCss
    ]
}

1.5 打包 图片、字体、媒体、等文件

file-loader就是将文件在进行一些处理后(主要是处理文件名和路径、解析文件url),并将文件移动到输出的目录中 url-loader一般与 file-loader搭配使用,功能与 file-loader 类似,如果文件小于限制的大小。则会返回 base64 编码,否则使用 file-loader 将文件移动到输出的目录中
npm i -D file-loader url-loader

配置如下

// webpack.config.js
module.exports = {
  // 省略其它配置 ...
  module: {
    rules: [
      // ...
      {
        test: /.(jpe?g|png|gif)$/i, //图片文件
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10240,
              fallback: {
                loader: 'file-loader',
                options: {
                    name: 'img/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/, //媒体文件
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10240,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'media/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /.(woff2?|eot|ttf|otf)(?.*)?$/i, // 字体
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 10240,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'fonts/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
    ]
  }
}

index.less文件修改

body{
 color: yellow;
 background: url("./images/webpack.jpeg")
}

当图片只有8kb时候,打包后Js如下

3b327ba38c046b31f8903b9fdaf4b799.png

当图片超过10KB,40KB的时候

d1b66b3989a1a5845bb2e688ca2336d9.png

会是这样一个效果,在dist目录下生成了一个img文件。

1.6 用babel转义js文件

为了使我们的js代码兼容更多的环境我们需要安装依赖

npm i babel-loader @babel/preset-env @babel/core
  • 注意

babel-loaderbabel-core的版本对应关系

  1. babel-loader 8.x 对应babel-core 7.x
  2. babel-loader 7.x 对应babel-core 6.x

配置如下

// webpack.config.js
module.exports = {
    // 省略其它配置 ...
    module:{
        rules:[
          {
            test:/.js$/,
            use:{
              loader:'babel-loader',
              options:{
                presets:['@babel/preset-env']
              }
            },
            exclude:/node_modules/
          },
       ]
    }
}

上面的babel-loader只会将 ES6/7/8语法转换为ES5语法,但是对新api并不会转换 例如(promise、Generator、Set、Maps、Proxy等)

此时我们需要借助babel-polyfill来帮助我们转换(这个问题以前面试的时候遇到过,囧,当时没回答上来)

npm i @babel/polyfill

注意,这里我把main.js改为了index.js

// webpack.config.js   
const path = require('path')
module.exports = {
    entry: ["@babel/polyfill,path.resolve(__dirname,'../src/index.js')"],    // 入口文件
}

好了,第一部分基础部分就到这里了,自己跟着敲打一遍还是有很多感悟和疑问的,实践完成之后我会总结一下。

第二部分有所不同,我想实现一个react的环境开发,而原文章中主要是vue的环境开发,我查阅一番资料,实现了在来补充。

下面是第二篇文章,搭建一个基础的react环境

林海:webpack实战第二篇(搭建react开发环境)​zhuanlan.zhihu.com
64c0fa048b6e813f7c56e4ba37f89927.png

和第三篇文章

林海:webpack实战第三篇(优化webpack)​zhuanlan.zhihu.com
64c0fa048b6e813f7c56e4ba37f89927.png

最后,原文连接在此,

https://segmentfault.com/a/1190000021395777​segmentfault.com
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值