从零开始用 webpack 搭建环境 :

个人博客迁移到biubu.cn,此处停更.请移步。

  • 1 必备条件 :

    • 1.1 nodejs 环境;
    • 1.2 当前以webpack 4.6 为主.
  • 2 核心概念

    • 2.1 入口(entry):

      入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的,每个依赖项随即被处理,最后输出到称之为 bundles 的文件中。

    • 2.2 出口(output)

      output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。你可以通过在配置中指定一个 output 字段,来配置这些处理过程.

    • 2.3 loader

      oader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

      在更高层面,在 webpack 的配置中 loader 有两个目标:

      • 2.3.1 test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
      • 2.3.2 use 属性,表示进行转换时,应该使用哪个 loader。
        下面是一个最基本的 webpack 配置:
        const path = require('path');
        
        const config = {
          entry: './path/to/my/entry/file.js',
          output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'my-first-webpack.bundle.js'
          },
          module: {
            rules: [
              { test: /\.txt$/, use: 'raw-loader' }
            ]
          }
        };
        
        module.exports = config;
        
    • 2.4 插件(plugins)

      loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

       以下是包含了 plugin 的 webpack 配置
    
        ```
          const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
                      const webpack = require('webpack'); // 用于访问内置插件
                      const path = require('path');
    
                      const config = {
                        entry: './path/to/my/entry/file.js',
                        output: {
                          path: path.resolve(__dirname, 'dist'),
                          filename: 'my-first-webpack.bundle.js'
                        },
                        module: {
                          rules: [
                            { test: /\.txt$/, use: 'raw-loader' }
                          ]
                        },
                        plugins: [
                          new webpack.optimize.UglifyJsPlugin(),
                          new HtmlWebpackPlugin({template: './src/index.html'})
                        ]
                      };
    
                      module.exports = config;
        ```
    
  • 3 配置步骤 :

    对基本概念有一个基本的了解之后,我们开始自己配置一个开发环境 ,首先,创建我们的项目目录 : 为了方便理解,直接在根目录下创建.

    • 3.1 生成 package.json 文件

      在当前项目目录用 npm init -y 生成 package.json文件,

    • 3.2 安装 webpackwebpack-cli

      在命令行输入 npm i webpack webpack-cli -S -D,这句命令的意思是安装开发依赖包 webpack webpack-cli ,并保存到 package.json 文件中.

    • 3.3 创建项目开发目录 src,

      并在 src 目录下创建 main.js 文件,main.js将作为我们的入口文件.

    • 3.4 在项目根目录创建 webpack.config.js.

    接下来我们开始配置 : webpack 最基本的配置要包含 入口出口;代码如下 :

    注 : path是nodejs的自带模块,直接引用即可使用,不需要单独去安装,该 模块提供了一些工具函数,用于处理文件与目录的路径。具体参看 官方文档

       const path = require('path');
    
                    const config = {
                      entry: 'main.js',
                      output: {
                        path: path.resolve(__dirname, 'dist'),
                        filename: 'my-first-webpack.bundle.js'
                      },
                      module: {
                        rules: [
                          { test: /\.txt$/, use: 'raw-loader' }
                        ]
                      }
                    };
    
                    module.exports = config;
    
    • 这样,一个最基本的 webpack 就配置完成了,在命令行输入 npx webpack即可正常运行.

      注 : 关于npx -- execute npm package binaries,说明一下 : npx 和 npm 类似,是安装完nodejs 后一起自带的,他的作用就是从 node_modules 目录的
      .bin 文件夹下寻找命令并执行,因为一般情况下我们的依赖都是本地安装,并不会全局安装,如果直接运行会报错报错内容一般是 * 无法将“xxxxx” 项识别为
      cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。*,用 npx options 就可以解决; 也可以将其通俗的理解为 .\node_modules\ .bin\xxxxx

  • 4 分离打包 css 文件 :

    项目中分离css 也是常见的需求,分离需要用到一个插件: extract-text-webpack-plugin,这个插件的作用就是将文件分离打包 : 首先,我们需要通过 npm 安装这个插件,这个插件是开发依赖,应该知道的命令是什么了吧?安装之后需要通过require 的方式将插件引入;

    这里注意一下,开头说了,我用的是webpack 4.6 版本,extract-text-webpack-plugin插件当前还不支持 webpack 4.6 ,因此,安装的时候使用命令 npm i extract-text-webpack-plugin@next --save-dev,如果过这个插件支持了webpack 4.x ,那就可以直接用npm i extract-text-webpack-plugin --save-dev安装了

    const ExtractTextPlugin = require ('extract-text-webpack-plugin');
    
    //引入之后要实例化插件
    
        plugins: [
            new ExtractTextPlugin ({
    
                // 打包后的文件路径以及文件名,路径以output的路径为基准.
                filename: 'css/[name][hash:10].css',
    
                // 禁用插件
                disable: false,
    
                // 从所有额外的 chunk(additional chunk) 提取(默认情况下,它仅从初始chunk(initial chunk) 中提取)
                // 当使用 `CommonsChunkPlugin` 并且在公共 chunk 中有提取的 chunk(来自`ExtractTextPlugin.extract`)时,`allChunks` **必须设置为 `true`
                allChunks: true,
    
                //禁用顺序检查 (这对 CSS 模块很有用!),默认 `false`
                ignoreOrder: false,
            })
        ]
    
  • 5 打包 html

    当前项目是单页面应用,也只有一个 index.html文件,打包之后,我们的 js 和CSS 文件是自动引入到 index.html 的,不需要在去手动操作;那还额外需要一个插件,就是 html-webpack-plugin,这个插件也是开发依赖,安装好之后通过 require 引入,这个插件的配置项参数有点多,我就不一一列举了,详情请参考 链接

        const HtmlWebpackPlugin = require ('html-webpack-plugin');
    
         plugins:[
             new HtmlWebpackPlugin ({
    
                // template是 webpack 打包时的需要参考模板,通俗的来说,
                // 就是打 包后的 `index.html` 需要用那一个作为模板.
                template: path.resolve (__dirname, '../index.html')
             }),
         ],
         module: {
                     rules: [
                          {
                             test: /\.css$/,
                             use: ExtractTextPlugin.extract({
                                 fallback:'style-loader',
                                 use:"css-loader",
                                 publicPath:"/dist"
                             })
                         },
                     ]
                 },
    

    通过以上配置步骤, webpack.config.js 应该是这样的

    const path = require ('path');
    const ExtractTextPlugin = require ('extract-text-webpack-plugin');
    const HtmlWebpackPlugin = require ('html-webpack-plugin');
    
    const config = {
        entry: 'main.js',
        output: {
            path: path.resolve (__dirname, 'dist'),
            filename: 'my-first-webpack.bundle.js'
        },
        module: {
            rules: [
                 {
                    test: /\.css$/,
                    use: ExtractTextPlugin.extract({
                        fallback:'style-loader',
                        use:"css-loader",
                        publicPath:"/dist"
                    })
                },
            ]
        },
    //引入之后要实例化插件
        plugins: [
            new ExtractTextPlugin ({
                // 打包后的文件路径以及文件名,路径以output的路径为基准.
                filename: 'css/[name][hash:10].css',
                // 禁用插件
                disable: false,
                allChunks: true,
                // 从所有额外的 chunk(additional chunk) 提取(默认情况下,它仅从初始chunk(initial chunk) 中提取)
                // 当使用 `CommonsChunkPlugin` 并且在公共 chunk 中有提取的 chunk(来自`ExtractTextPlugin.extract`)时,`allChunks` **必须设置为 `true`
                //禁用顺序检查 (这对 CSS 模块很有用!),默认 `false`
                ignoreOrder: false,
            }),
    
            new HtmlWebpackPlugin ({
                title: 'OutPut managerment',
                inject: true,
                template: path.resolve (__dirname, '../index.html')
            }),
        ]
    };
    module.exports = config;
    
    

    基于以上的配置文件,已经解决,接下来,我们解决开发环境的问题 :

  • 6 开发环境搭建 :

    • 6.1 安装 webpack-dev-server一样的,还是开发依赖.
    • 6.2 配置 devServer,参数有点多,不一一列举了,官方文档也很详细, 点击查看
    devServer : {
    
    }
    

    最后,在 package.json 的 script 字段添加一下内容,就可以通过 npm run dev 或者 npm run build 来运行了,不用每次都输入 webpack-dev-server --open --config webpack.config.js或者 webpack --progress --color --config webpack.config.js

    "scripts": {
            "dev": "webpack-dev-server --open --config config/webpack.dev.js",
            "build": "webpack --progress --color --config config/webpack.prod.js"
        },
    

    这样打包的有一点不完美的地方: 就是dist 文件夹下面的 js 文件和 index.html 在同一个目录,一般情况下,我们都是的目录文件都是 css 和js 都在单独的目录中,这个问题的解决办法就是在 output.filename前面加上js 文件夹即可,

     output: {
            path: path.resolve (__dirname, 'dist'),
            filename: '/js/my-first-webpack.bundle.js'
        },
        ```
    

推荐阅读更多精彩内容