打包工具:Webpack

参考:

  官网:https://webpack.js.org/guides/getting-started/

  原文:https://segmentfault.com/a/1190000021395777

  本文demo(webpack5):https://gitee.com/open_-_code/webpack_demo.git

webpack demo

  1 初始化项目

    初始化npm

npm init -y

    安装依赖

npm install webpack webpack-cli --save-dev

    创建src文件,src下创建index.js

    

// index.js
console.log('hello webpack')

    配置package.json

  "scripts": {
    "build": "webpack"
  },

    执行npm run build

    此时如果生成了一个dist文件夹,并且内部含有main.js说明已经打包成功了

  2 配置自己的配置

    新建一个webpack.config.js

    

// webpack.config.js
const path = require('path');

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

    更改package.json

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

    执行npm run build,其中dist文件夹中的main.js就是我们需要在浏览器中实际运行的文件

  3 配置html模板

    为了缓存,日常开发时,webpack.config.js往往会这样配置

// webpack.config.js
const path = require('path');

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

    你会发现打包好的js文件的名称每次都不一样

    

     webpack打包出来的js文件我们需要引入到html中,但是每次我们都手动修改js文件名显得很麻烦,因此我们需要一个插件来帮我们完成这件事情

npm i -D html-webpack-plugin

    新建文件夹public,里面新建一个index.html

    引入插件html-webpack-plugin,修改webpack.config.js

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

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

    执行打包命令,打包生成的js文件已经被自动引入html文件中

    

     多文件入口开发,修改webpack.config.js

// webpack.config.js    
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'] // 与入口文件对应的模块名
        }),
]

    执行打包命令生成目录

    

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

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

  4 引入css

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

// index.js

import '/src/assets/index.css'
import '/src/assets/index.less'
console.log('hello webpack')

    同时我们也需要一些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'] // 从右向左解析原则
        }
      ]
    }
}

    执行打包命令,浏览器打开dist下的index.html

    

   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'] // 从右向左解析原则
          }
      ]
    }
}

    根目录下创建postcss.config.js

// postcss.config.js

module.exports = () => {
    return {
        plugins: {
            'autoprefixer': {
                overrideBrowserslist: ['Android >= 4.0', 'iOS >= 7']
            },
        }
    }
}

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

  4.2 拆分css

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

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

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

      file-loader就是将文件在进行一些处理后(主要是处理文件名和路径、解析文件url),并将文件移动到输出的目录中

      url-loader 一般与file-loader搭配使用,功能与 file-loader 类似,如果文件小于限制的大小。则会返回 base64 编码,否则使用 file-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]'
                }
              }
            }
          }
        ]
      },
    ]
  }
}

  

  6 用babel转义js文件

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

    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等)

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

    over!!

原文地址:https://www.cnblogs.com/jing-zhe/p/14201893.html