暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

前端工程化之webpack篇-第一章(学会搭建webpack环境)

从0到1技术进阶 2021-09-06
430

01  前言

Webpack 是一个 JavaScript 应用程序的静态模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个包。

Webpack 功能包括:

  1. 代码转换

  2. 文件优化

  3. 代码分割

  4. 模块合并

  5. 自动刷新

  6. 代码校验

  7. 自动发布

阅读本文以及使用你需要有简单的node 基础 ,打开node 官方网站进行安装node, http://nodejs.cn/ 下载最新版node包并进行安装。

02  搭建环境

当你安装完成Node环境之后,找到你要新建的工程的位置(使用终端):

之后执行如下步骤:

1.快速创建node项目 执行命令npm init -y 生成packge.json

2.在当前目录安装本地webpack,终端执行命令:

    npm i webpack webpack-cli -d

    ps:   i表示install ,d表示当前是开发环境安装完成会产生node_modules文件

    等待命令执行完毕,显示如下:

    当然!webpack 可以进行0配置 并且webpack是打包工具(默认是js模块 通过入口进行打包输出打包后js结果)。

    为了测试,我们执行如下步骤:

    1.创建好src目录并在里面新建一个index.js文件,键入console.log('Hello World!');   //这个老生常谈了啊

    2.使用npx进行打包,执行npx webpack

    3.我们发现当前目录生成了一个dist 目录并且创建了一个main.js(如图:)

    默认执行顺序:(node_modules/bin/webpack文件 )

    如上图可以看到我们需要装好webpack的脚手架进行操作。

    webpack打包默认支持js模块化

    webpack:两种默两种模式如果没有创建webpack.config.js 配置文件指定mode (production/development)生成模式或开发模式,打包运行会直接默认生产模式打包并且进行压缩。

    这里说一下webpack配置文件的默认名称有两种 (webpack.config.js webpackfile.js 一般情况下我们会选择前一种)。


    03  前言手动配置webpack

    1.创建webpack.config.js 文件 

    由于webpack是node.js的框架所以配置文件中要采用node语法来进行编辑。

    如何更改webpack 配置文件名称呢?其实很简单,重命名webpack.config.js (webpack.test.js)
    执行命令:npx webpack --config webpack.test.js  也可以执行webpack打包。
    但是这样打包我们发现命令很长,所以要利用packge.json 来配置打包脚本,在scripts-->添加build如下:

    之后再终端运行 npm run build 发现执行打包结果一样!

    2.安装webpck内置服务

    安装webpck内置服务 webpack-dev-server 好处是运行时不会生成文件,而是生成内存中的打包

    终端执行命令: 

      npm i webpack-dev-server -d -save

      安装完成可以执行:

         npx webpack-dev-server

        按提示打开http://localhost:8888/

        配置开发服务运行目录,可以在配置文件中添加在webpack.test.js添加devServer

          devServer: {
          //开发服务器配置
          contentBase: './build', //指向打包目录
          port: 8888, //服务端口号
          progress: true, //打包进度
          open: true, //是否打开浏览器
          compress: false, //是否压缩
          },

          在packge.json中添加start 启动服务脚本

              "scripts": {
            "test": "echo \"Error: no test specified\" && exit 1",
            "build": "webpack --config webpack.test.js",
            "start":"webpack-dev-server"
            },

            运行 npm run start 发现没有自动创建index.html 不能直观看到我们代码在浏览器的执行。

            在src目录下创建html模板 index.html 并安装 html-webpack-plugin 插件
            终端运行: 

              npm i -d html-webpack-plugin

                在webpack.config.js 下添加插件配置plugins


                plugins: [
                //数组形式 存放所有的webpack插件
                new HtmlWebPackPlugin({
                filename: "index.html", //生成打包文件名
                template: "./src/index.html", //模板路径
                minify: { //生产模式可以进行配置
                removeAttributeQuotes: true, //删除 html文件双引号
                collapseWhitespace: true //折叠控行
                },
                hash:true, //添加哈希值
                })
                ]


                终端执行打包测试:npm run build (build目录下生成了我们想要生成的index.html文件)


                04  样式的配置 --- webpack配置css模块

                配置样式需要一个合适loader,loader会将我们的样式文件解析成模块(module)
                终端:

                  npm i -d --save css-loader style-loader

                  如何使用样式loader进行配置呢?我们先在src下建index.css并给body赋予简单样式
                  在webpack.test.js 进行简单配置,添加module与plugins同级。
                  css-loader主要解析我们样式中@import语法,style-loader是吧css样式插入head标签中.

                    module: {
                    //添加模块模块是对象
                    rules: [
                    //规则 css-loader主要解析我们样式中@import语法
                    {
                    test: /\.css$/,
                    use: ['style-loader', 'css-loader'], //执行顺序是重右向左执行 - >重下到上
                    },
                    ],
                    },

                    在index.js中引入样式文件 import './index.css'
                    终端运行:npm run start 样式生效了同样我们也有对应的less less-loader
                    终端:

                      npm i -d --save less less-loader

                      在这里说一下loader 的另一种写法对象写法可以给loader添加一些属性options

                        module: {
                        //添加模块模块是对象
                        rules: [
                        //规则 css-loader主要解析我们样式中@import语法
                        {
                        test: /\.css$/,
                        use: [
                        {
                        loader: "style-loader",
                        options: {
                        insertAt: "top" //把标签插入顶部
                        }
                        },
                        "css-loader"
                        ] //执行顺序是重右向左执行 - >重下到上
                        },
                        {
                        test: /\.less$/,
                        use: [
                        {
                        loader: "style-loader",
                        options: {
                        insertAt: "top" //把标签插入顶部
                        }
                        },
                        "css-loader",
                        "less-loader"
                        ] //执行顺序是重右向左执行 - >重下到上
                        }
                        ]
                        }

                        css 样式的抽离 安装抽离插件 mini-css-extract-plugin

                          npm i -d --save mini-css-extract-plugin

                          引入插件并在配置文件中进行配置

                            const path = require('path'); //webpack内部方法path组件
                            const HtmlWebPackPlugin = require('html-webpack-plugin');
                            const MinCssExtractPlugin = require('mini-css-extract-plugin'); //抽离css插件




                            module.exports = {
                            mode: 'development', //打包模式 development开发模式
                            entry: './src/index.js', //入口文件指定
                            output: {
                            //出口文件配置 配置出口打包路径
                            filename: 'build.js', //打包后的文件名称
                            path: path.resolve(__dirname, 'build'), //resolve绝对路径引入
                            },
                            devServer: {
                            //开发服务器配置
                            contentBase: './build', //指向打包目录
                            port: 8888, //服务端口号
                            progress: true, //打包进度
                            open: true, //是否打开浏览器
                            compress: false, //是否压缩
                            },
                            //插件
                            plugins: [
                            //数组形式 存放所有的webpack插件
                            new HtmlWebPackPlugin({
                            filename: 'index.html', //生成打包文件名
                            template: './src/index.html', //模板路径
                            minify: {
                            //生产模式可以进行配置
                            removeAttributeQuotes: true, //删除 html文件双引号
                            collapseWhitespace: true, //折叠控行
                            },
                            hash: true, //添加哈希值
                            }),
                            ,
                            new MinCssExtractPlugin({
                            filename: 'mian.css',
                            }),
                            ],
                            module: {
                            //添加模块模块是对象
                            rules: [
                            //规则 css-loader主要解析我们样式中@import语法
                            {
                            test: /\.css$/,
                            use: [
                            MinCssExtractPlugin.loader, //创建link标签放入到main.css里
                            'css-loader',
                            ], //执行顺序是重右向左执行 - >重下到上
                            },
                            {
                            test: /\.less$/,
                            use: [
                            MinCssExtractPlugin.loader, //创建link标签放入到main.css里
                            'css-loader',
                            'less-loader',
                            ], //执行顺序是重右向左执行 - >重下到上
                            },
                            ],
                            },
                            };

                            添加样式前缀 postcss-loader autoprefixer

                              npm i postcss-loader autoprefixer -d
                                module: {
                                //添加模块模块是对象
                                rules: [
                                //规则 css-loader主要解析我们样式中@import语法
                                {
                                test: /\.css$/,
                                use: [
                                MinCssExtractPlugin.loader, //创建link标签放入到main.css里
                                "css-loader",
                                "postcss-loader"
                                ] //执行顺序是重右向左执行 - >重下到上
                                },
                                {
                                test: /\.less$/,
                                use: [
                                MinCssExtractPlugin.loader, //创建link标签放入到main.css里
                                "css-loader",
                                "postcss-loader",
                                "less-loader"
                                ] //执行顺序是重右向左执行 - >重下到上
                                }
                                ]
                                }

                                注意 postcss-loader 需要添加一个配置文件否则不会生效,在根目录创建postcss.config.js

                                  module.exports = {
                                  plugins: [require("autoprefixer")]
                                  };

                                  但是我们发现问题使用mini-css-extract-plugin插件导致我们css不会被压缩。这里要使用optimize-css-assets-webpack-plugin 插件接下来我们安装配置一下.:

                                    npm i -d optimize-css-assets-webpack-plugin
                                      const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //压缩js
                                      //配置文件中添加优化项
                                      optimization: {
                                      minimizer: [new OptimizeCSSAssetsPlugin({})]
                                      }

                                      使用optimize-css-assets-webpack-plugin我们发现js又不会被压缩 ,所以要使用uglifyjs-webpack-plugin --save-dev

                                        npm install uglifyjs-webpack-plugin --save-dev
                                            optimization: {
                                          minimizer: [new OptimizeCSSAssetsPlugin({}), new UglifyJsPlugin()],
                                          },


                                          05  语法的转换神器 --- babel

                                          为了验证,我们首先在index.js添加如下代码:

                                            let fn = () => {
                                            console.log("es6 webpack");
                                            };
                                            fn();

                                            终端执行: npx webpack 查看打包文件

                                            我们发现打包出来的仍然是es6语法这个时候我们需要一个loader 进行转换 babel-loader babel @babel/core

                                            (babel/core是@babel-loader的核心组件转化模块@babel/preset-env)

                                              npm i -d babel-loader babel @babel/core @babel/preset-env

                                              在module添加配置

                                                {
                                                test: /\.js$/,
                                                use: [
                                                {
                                                loader: "babel-loader",
                                                options: {
                                                //转化es5语法--presets预设
                                                presets: ["@babel/preset-env"]
                                                }
                                                }
                                                ]
                                                },

                                                终端运行:npm run build

                                                发现可以已经转换es6语法 但是仅仅这样不能转换es6高阶语法比如一些特殊的类函数:

                                                  class Test {
                                                  // new Test() a =1 实例上添加a属性 这个语法属于es7语法打包时发现并不能解析
                                                  a = 1;
                                                  }

                                                  终端运行:npm run build 发现报错提示安装 @babel/plugin-proposal-class-properties

                                                  那我们按照要求按照一下插件 

                                                    npm i -d @babel/plugin-proposal-class-properties 

                                                    再次配置一下:

                                                      {
                                                      test: /\.js$/,
                                                      use: [
                                                      {
                                                      loader: "babel-loader",
                                                      options: {
                                                      //转化es5语法--presets预设
                                                      presets: ["@babel/preset-env"],
                                                      plugins: ["@babel/plugin-proposal-class-properties"]
                                                      }
                                                      }
                                                      ]
                                                            },

                                                      再次打包,成功!

                                                      转化完语法接下来看一下babel语法的校验 

                                                        npm i -d @babel/plugin-transform-runtime @babel/runtime

                                                        然后配置一下:

                                                          {
                                                          test: /\.js$/,
                                                          use: {
                                                          loader: 'babel-loader',
                                                          options: {
                                                          //转化es5语法--presets预设
                                                          presets: ['@babel/preset-env'],
                                                          plugins: [
                                                          ['@babel/plugin-proposal-decorators', { legacy: true }],
                                                          ['@babel/plugin-proposal-class-properties', { loose: true }],
                                                          [
                                                          '@babel/plugin-transform-runtime',
                                                          {
                                                          absoluteRuntime: false,
                                                          corejs: false,
                                                          helpers: true,
                                                          regenerator: true,
                                                          useESModules: false,
                                                          },
                                                          ],
                                                          ],
                                                          },
                                                          },
                                                          include: path.resolve(__dirname, 'src'), //只找__dirname - >src
                                                          exclude: /node_modules/, //忽略node_modulse
                                                          },

                                                          includes 实例方法不被解析 需要一个补丁模块@babel/polyfill

                                                            npm install --save @babel/polyfill

                                                            polyfill可以直接在js里面引入

                                                            接下来看一下代码校验ESLint代码校验工具

                                                              npm i -d eslint eslint-loader

                                                              根据项目需求下载对应的eslintrc.json , https://eslint.org/demo/

                                                              以上便是webpack学习的第一步,如果你已经按照教程走过一遍,下一篇我们再继续讲一些进阶的配置。


                                                              文章转载自从0到1技术进阶,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                              评论