Webpack 基础

基本使用

  1. 初始化,会创建一个 package.json 文件(包属性说明文件)

    npm init -y

  2. 安装 webpack-cli ,这个工具用于在命令行中运行 webpack

    npm install webpack webpack-cli --save-dev

  3. 修改 package.json 文件

    +  "private": true, # 将打包器改为私有
    -  "main": "index.js", # 去掉入口文件,放置打包意外发布
    
  4. 创建源代码目录,一般情况下源码放在 /src 目录中。

  5. 创建分发代码目录(即打包发布代码),一般情况下分发代码放在 /dist 目录中。

  6. 创建 webpack 配置文件,webpack.config.js 文件。

  7. /dist 中创建 index.html 文件,在/src 中创建 index.js 文件,index.html 作为项目的入口文件,index.js 作为项目入口文件 index.html 的依赖文件,此时项目目录为:

    webpack-demo
      |- package.json
      |- webpack.config.js
      |- /dist
         |- index.html
      |- /src
         |- index.js
    

    webpack.config.js

    const path = require("path")
    
    module.exports = {
    	entry: './src/index.js',
    	output: { //__dirname 是设置文件的存放目录
    		filename: 'main.js', //输出文件重命名
    		path: path.resolve(__dirname, 'dist') //输出文件存放地址
    	}
    }
    

    index.html

    <html>
    <head>
    </head>
    <body>
        <p>webpack示例</p>
    	<script src="main.js"></script>
    </body>
    </html>
    

    index.js

    window.onload = function(){
    	console.log("hello")
    }
    
  8. 使用配置文件打包,npx webpack --config webpack.config.js

    打包成功后会在分发代码目录输出入口文件(mian.js)。


概念

  1. entry 入口:设置打包器的起点(主页引用的js文件)。配置:

    module.exports = {
        entry: './entry.js'  //设置entery.js文件为入口起点
    }
    
  2. output 出口:设置打包的输出路径,以及如何命名打包文件,默认输出路径为./dist。配置:

    const path = require('path') //引入node.js中的path模块
    moudle.exports = {
        output: {
            path: path.resolve(_dirname, 'dist'), 
            //设置输出路径,path.resolve()是node.js的路径操作方法。
            filename: 'filename.bundle.js'
            //设置打包文件名
        }
    }
    
  3. loader 装载:webpack只能处理JavaScript文件,loader的作用是将非JavaScript文件转换为webpack能够处理的文件。配置:

    const path = require('path')
    const config = {
        moudle: {
            rules: [
                {test: /\.txt$/, use: 'raw-loader'}
                //当碰到.txt路径的文件时,使用raw-loader转换一下再打包。
            ]
        }
    }
    module.exports = config
    
  4. plugins 插件:loader用于转换某些类型的模块,plugins用于解决loader解决不了的事情。配置:

    const HtmlWebpackPlugin = require('html-webpack-plugin') //通过npm安装
    const webpack = require('webpack')  //访问内置插件
    const config = {
        plugins: [
            new HtmlWebpackPlugin({template: './index.html'})
        ]
    }
    module.exports = config
    
  5. mode 模式:通过选择developmentproduction之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化。配置:

    module.exports = {
      mode: 'production'
    }
    
  6. vue.config.js 是vue-cli的webpack的配置,没有的话在项目跟目录下创建一个即可。


管理资源

通过插件让 webpack 能够处理非 JavaScript 的方式完成对资源的管理使用。

基本使用

  • 加载 CSS ,安装依赖的软件包,npm install --save-dev style-loader css-loaderCSS 文件是用过 import 'url' 引入相应的 .js 文件中的。

  • 加载图片,安装依赖的软件包,npm install --save-dev file-loader ,图片是在

  • 加载字体,file-loaderurl-loader 可以接收并加载任何文件,然后将其输出到构建目录,加载字体文件直接加载即可。

  • 加载数据(CSVTSVXML),安装依赖的软件包,npm install --save-dev csv-loader xml-loader

  • 示例:

    webpack.config.js

    const path = require('path')
    
    module.export = {
        enter: {},
        output: {},
        module: {
            rules: [
                { //加载css文件
                    test: /\.css$/, //根据正则表达式的语法,匹配所有以 .css 结尾的文件
                    use: [ //文件的处理模块
                        'style-loader',
                        'css-loader'
                    ]
                },
                { //加载图片
                    test: /\.(png|svg|jpg|gif)$/,
                    use: [
                        'file-loader'
                    ]
                },
                { //加载字体
                    test: /\.(woff|woff2|eot|ttf|oft)$/,
                    use: [
                        'file-loader'
                    ]
                },
                { //加载 csv、tsv 数据
                    test: /\.(csv|tsv)$/,
                    use: [
                        'csv-loader'
                    ]
                },
                { //加载 xml 数据
                    test: /\.xml$/,
                    use: [
                        'xml-loader'
                    ]
                }
            ]
        }
    }
    

    此时项目目录:

    webpack-demo
      |- package.json
      |- webpack.config.js
      |- /dist
         |- index.html
      |- /src
         |- index.js
         |- index.css
         |- ex.tff
         |- ex.jpg
    

    index.css

    @font-face { /*引入字体文件*/
    	font-family: "ex";
    	src: url("./ex.ttf");
    }
    
    body {
    	font-family: "ex"; /*设置使用字体*/
    	color: blue;
    	background: url("./ex.jpg"); /*设置背景图片*/
    }
    

输出管理

管理输出是指使用 webpack 自动的将有关联的文件关联起来,如在 index.html 文件中引入 index.js 文件一般需要在 index.html 中使用 <script> 标签,而管理输出的目的是让有关联的文件自动的关联起来,不用在文件中显示引入。

基本使用

  • 管理输出,引入依赖包: npm install --save-dev html-webpack-plugin

  • 清理 /dist 文件夹,引入依赖包: npm install clean-webpack-plugin --save-devwebpack 不会自动清理输出文件夹,避免文件夹中积累上次的打包文件,可以设置清理输出文件夹然后再打包。

  • 示例:

    webpack.config.js

    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    
    module.exports = {
        entry: { //入口文件依赖
            index: './src/index.js',
            one: './src/one.js'
        },
        plugins: [
            new CleanWebpackPlugin(), //默认清除输出文件目录
            new HtmlWebpackPlugin({ //管理输出
                template: path.resolve(__dirname, './src/index.html'), //入口文件
                chunks: ["index", "one"] //入口文件依赖
            })
        ],
        output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'dist')
        }
    }
    

    此时文件目录:

    webpack-demo
      |- package.json
      |- webpack.config.js
      |- /dist
      |- /src
         |- index.html
         |- index.js
         |- one.js
         |- index.css
         |- ex.tff
         |- ex.jpg
    

开发环境

webpack 打包源代码时,会有很难追踪到错误和警告在源代码中的原始位置等问题,开发的目的就是使错误追踪等能够映射到源代码文件,使代码热更新,浏览器自动刷新等问题。

基本使用

  • 追踪错误源代码,在 webpack.config.js 文件中使用 inline-source-map 选项。

  • 使用 npx webpack --watch 命令启动观察者模式打包,此时打包完成命令不会退出,当代码有变化时,会实时响应。

  • 浏览器自动刷新,安装相应依赖包,npm install --save-dev webpack-dev-server ,并使用 npx webpack-dev-server --open 启动服务器,浏览器自动刷新会默认使用观察者模式。

    浏览器自动刷新,安装相应依赖包, npm install --save-dev express webpack-dev-middlewarewebpack-dev-middleware 是一个容器,可以把 webpack 处理后的文件传递给一个服务其, webpack-dev-server 是内置了 webpack-dev-middleware ,但单独使用 webpack-dev-middleware 能更灵活的配置自定义设置。(使用方式略过)

  • 示例:

    webpack.config.js

    const path = require("path")
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    
    module.exports = {
        entry: {},
        devtool: "inline-source-map", //追踪错误源码
        devServer: { //浏览器自动刷新
          contentBase: './dist' //将 dist 目录下的文件,作为可访问文件。
        },
        plugins: [],
        output: {}
    }
    

生产环境

为开发环境和生产环境构建不一样的 webpack.config.js 配置文件。

基本使用

  • 安装依赖包:npm install --save-dev webpack-merge ,将 webpack.config.js 拆分成 webpack.common.js (通用)和 webpack.dev.js (开发环境) 、 webpack.prod.js (生产环境) 三个文件,其中通用的文件是开发环境和生产环境公用的配置。

  • 启用开发环境打包: npx webpack --config webpack.dev.js

  • 启用生产环境打包: npx webpack --config webpack.prod.js

  • 示例:

    webpack.common.js

    const path = require("path")
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    
    module.exports = {
    	entry: {
            index: './src/index.js',
            one: './src/one.js'
        },
    	plugins: [
    	    new CleanWebpackPlugin(),
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, './src/index.html'),
                chunks: ["index", "one"]
            })
        ],
    	output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'dist')
        },
    	module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [
                        'style-loader',
                        'css-loader'
                    ]
                },
    			{
                    test: /\.(png|svg|jpg|gif)$/,
                    use: [
                        'file-loader'
                    ]
                },
    			{
                    test: /\.(woff|woff2|eot|ttf|oft)$/,
                    use: [
                        'file-loader'
                    ]
                }
            ]
        } 
    }
    

    webpack.dev.js 配置

    const {merge} = require('webpack-merge')
    const common = require('./webpack.common.js')
    
    module.exports = merge(common, {
        devtool: 'inline-source-map',
    })
    

    webpack.prod.js 配置

    const {merge} = require('webpack-merge')
    const common = require('./webpack.common.js')
    
    module.exports = merge(common, {
    })
    

    此时文件目录为:

    webpack-demo
      |- package.json
      |- webpack.common.js
      |- webpack.dev.js
      |- webpack.prod.js
      |- /dist
      |- /src
         |- index.html
         |- index.js
         |- one.js
         |- index.css
         |- ex.tff
         |- ex.jpg
    

代码分离

代码分离是将代码分离到更小的文件中,然后按需加载,代码分离可以获得更小的文件以及控制资源加载的优先级,使用得当的话,会极大提升加载时间。有三种常用的分离方法:

  1. 入口起点:使用 entry 配置手动分离代码,即手动的将入口模块才分开来。
  2. 防止重复:使用 CommonsChunkPlugin 去重和分离 chunk 。即将入口起点分为多个模块时,假如多个模块引用了同一个依赖,已导入依赖重复引入,防止重复就是以将重复的依赖单独提取到一个模块中去防止重复导入的方法。
  3. 动态导入:通过模块的内敛函数调用来分离代码。

入口起点:webpack.config.js 配置

module.exports = {
    entry: {//两个入口文件
        one: './src/one.js',
        two: './src/one.js'
    }
}

防止重复:webpack.config.js 配置

const webpack = require('webpack')

module.exports = {
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common' //提取的公共模块的打包文件名
        })
    ]
}

配置示例

const path = require('path');  //引入node.js内置的处理路径的path模块
const HtmlWebpackPlugin = require('html-webpack-plugin');//用于生成入口文件的模块,需要安装(npm i -D html-webpack-plugin)
const {CleanWebpackPlugin} = require('clean-webpack-plugin');//用于清空上一次打包文件夹内的打包文件,需要安装(npm install clean-webpack-plugin)
//解析CSS,需要根据使用CSS文件类型安装响应程序包,.css文件安装(npm install --save-dev style-loader css-loader)
const MiniCssExtractPlugin = require("mini-css-extract-plugin");//用于将引入的css文件提取成单独的文件,一般情况下系统默认把css文件提取到js文件中。
[const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); 用于将单独的css文件打包成单独的css文件,"mini-css-extract-plugin"会把所有的css文件打包成一个css文件。使用实例暂略。]
//打包图片,打包字体文件,打包媒体文件,需要安装(npm install --save-dev file-loader)

module.exports = {
  mode: 'development', //开发模式打包的文件模式,production是生产模式
  entry: {//入口文件,就是index.html文件需要引入多少js文件,可以一个html对应一个或多个入口js文件。
      main: path.resolve(__dirname, 'url')//入口文件的路径
      one: path.resolve(__dirname, 'url')//__dirname是当前配置文件所在的路径
      two: path.resolve(__dirname, 'url')//url是入口文件相对于配置文件的路径
  },
  output: {//出口文件,就是打包后的文件的配置
    filename: '[name].[hash:8].js',//打包后的文件名,[name]表示保留原文件名,[hash:8]表示生成随机的字符
    path: path.resolve(__dirname, 'dist')  //打包文件的输出目录
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve('__dirname,'url/xxx.html''),//引用入口文件的HTML文件路径
      filename: 'index.html',//打包后的HTML的文件名
      chunks: ['main', 'one']//需要引入的入口js文件列表,这个html文件引入两个js文件
    }),
    new HtmlWebpackPlugin({
      template: path.resolve('__dirname,'url/xxx.html''),//引用入口文件的HTML文件路径
      filename: 'two.html',//打包后的HTML的文件名
      chunks: ['two']//需要引入的入口js文件列表,这个html文件引入一个js文件
    }),
    new CleanWebpackPlugin(),//清空上一次打包的打包文件
    new MiniCssExtractPlugin({
        filename: '[name].[hash:8].css',//打包后的css文件名
        chunkFilename: '[id].css'//识别需要引入的入口js文件中的css文件
    })
  ],
  moudle: {//用于对模块的源代码进行转换
    rules: [
      {//打包在入口JS文件中使用import引入的css样式表
        test: /\.css$/,//检查文件类型
        use: [//使用模块,注意模块的调用顺序,从数组右边往左边走
          MiniCssExtractPlugin.loader//将人口js引入的css文件提取到单独css文件中,不能和'style-loader'同时使用
          'style-loader',//把css文件引入js入口文件,css会放入入口js文件中,不能和MiniCssExtractPlugin.loader同时使用
          'css-loader',//打包css使用的模块,
        ]
      },
    ]
  }
};