记录一下使用webpack+vue创建项目流程和常用的插件

记录一下使用webpack+vue创建项目流程和常用的插件

1.项目初始化
npm init
2.安装webpack
npm i webpack webpack-dev-server
3.创建配置文件
//项目文档结构
web
├─package-lock.json
├─package.json
├─src
|  └main.js
├─scripts // 构建脚本文件夹
|    ├─dev.js //开发环境构建脚本
|    ├─prod.js //生产环境构建脚本
|    ├─config // 构建脚本配置文件夹
|    |   ├─index.js // webpack配置文件 导出开发与生产配置函数
|    |   ├─util.js // 导出工具函数
|    |   ├─plugin // 封装插件文件夹
|    |   |   └index.js
|    |   ├─loader // 封装loaders文件夹
|    |   |   └index.js
├─public
|   └index.html // html模板
├─dist // 打包输出路径
4.loaders

注意:第4,第5步为常用loader和plugin介绍

  • thread-loader

    //安装 使用时,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行
    npm install --save-dev thread-loader
    
    //webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.js$/,
            include: path.resolve("src"),
            use: [
              "thread-loader",
              // 耗时的 loader (例如 babel-loader)
            ]
          }
        ]
      }
    }
    
    
  • babel-loader

    //当前演示webpack使用方法 其他参照babel官网
    //安装
    npm install --save-dev babel-loader @babel/core
    
    //webpack.config.js
    module: {
      rules: [
        { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
      ]
    }
    
    //创建 .babelrc 配置文件
    //安装插件 使用转换 ES2015+ 的 env preset 
    npm install @babel/preset-env --save-dev 
    
    //.babelrc
    {
      "presets": ["@babel/preset-env"]
    }
    
  • eslint-loader

    //安装
    npm install eslint --save-dev //安装eslint
    npm install eslint-loader --save-dev //安装eslint-loader
    
    //webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: ['babel-loader', 'eslint-loader'],
          },
        ],
      },
    };
    
    
    
    
  • style-loader

    //安装
    npm install --save-dev style-loader
    //webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader'],
          },
        ],
      },
    };
    
    
    • css-loader

      //安装
      npm install --save-dev css-loader
      
      //webpack.config.js
      module.exports = {
        module: {
          rules: [
            {
              test: /\.css$/i,
              use: ['style-loader', 'css-loader'],
            },
          ],
        },
      };
      
  • postcss-loader

    npm i -D postcss-loader
    
    //postcss.config.js
    module.exports = {
      parser: 'sugarss',
      plugins: {
        'postcss-import': {},
        'postcss-cssnext': {},
        'cssnano': {}
      }
    }
    //webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [ 'style-loader', 'postcss-loader' ]
          }
        ]
      }
    }
    
  • less-loader

    //安装
    npm install --save-dev less-loader less
    
    // webpack.config.js
    module.exports = {
        ...
        module: {
            rules: [{
                test: /\.less$/,
                use: [{
                    loader: "style-loader" // creates style nodes from JS strings
                }, {
                    loader: "css-loader" // translates CSS into CommonJS
                }, {
                    loader: "less-loader" // compiles Less to CSS
                }]
            }]
        }
    };
    
  • Sass-loader

    npm install sass-loader node-sass webpack --save-dev
    // webpack.config.js
    module.exports = {
      ...
      module: {
        rules: [{
          test: /\.scss$/,
          use: [{
              loader: "style-loader" // 将 JS 字符串生成为 style 节点
          }, {
              loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
          }, {
              loader: "sass-loader" // 将 Sass 编译成 CSS
          }]
        }]
      }
    };
    
  • Vue-loader

    //安装
    npm install -D vue-loader vue-template-compiler
    
    // webpack.config.js
    const VueLoaderPlugin = require('vue-loader/lib/plugin')
    
    module.exports = {
      module: {
        rules: [
          // ... 其它规则
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          }
        ]
      },
      plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin()
      ]
    }
    
  • Url-loader

    //安装
    npm install --save-dev url-loader
    
    module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 8192
                }
              }
            ]
          }
        ]
      }
    }
    
  • File-loader

    //安装
    npm install --save-dev file-loader
    
    module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: 'file-loader',
                options: {}
              }
            ]
          }
        ]
      }
    }
    
5.plugins
  • mini-css-extract-plugin

    //安装
    npm install --save-dev mini-css-extract-plugin
    
    //webpack.config.js
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      plugins: [new MiniCssExtractPlugin()],
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
          },
        ],
      },
    };
    Options
    
    
  • html-webpack-plugin

    //安装
    npm install --save-dev html-webpack-plugin
    
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var path = require('path');
    
    var webpackConfig = {
      entry: 'index.js',
      output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'index_bundle.js'
      },
      plugins: [new HtmlWebpackPlugin()]
    };
    
  • clean-webpack-plugin

    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
     
    const webpackConfig = {
        plugins: [
            /**
             * All files inside webpack's output.path directory will be removed once, but the
             * directory itself will not be. If using webpack 4+'s default configuration,
             * everything under <PROJECT_DIR>/dist/ will be removed.
             * Use cleanOnceBeforeBuildPatterns to override this behavior.
             *
             * During rebuilds, all webpack assets that are not used anymore
             * will be removed automatically.
             *
             * See `Options and Defaults` for information
             */
            new CleanWebpackPlugin(),
        ],
    };
     
    module.exports = webpackConfig;
    
  • optimize-css-assets-webpack-plugin

    npm install --save-dev optimize-css-assets-webpack-plugin
    
    var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
            loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
          }
        ]
      },
      plugins: [
        new ExtractTextPlugin('styles.css'),
        new OptimizeCssAssetsPlugin({
          assetNameRegExp: /\.optimize\.css$/g,
          cssProcessor: require('cssnano'),
          cssProcessorPluginOptions: {
            preset: ['default', { discardComments: { removeAll: true } }],
          },
          canPrint: true
        })
      ]
    };
    
  • terser-webpack-plugin

    npm install terser-webpack-plugin --save-dev
    
    const TerserPlugin = require('terser-webpack-plugin');
     
    module.exports = {
      optimization: {
        minimize: true,
        minimizer: [new TerserPlugin()],
      },
    };
    
  • HotModuleReplacementPlugin

    const { HotModuleReplacementPlugin } = require('webpack');
    
    const webpackConfig = {
        plugins: [
            new HotModuleReplacementPlugin();
        ],
    };
     
    module.exports = webpackConfig;
    
    
6.环境构建
  • 开发环境

    //使用nodeAPI构建开发环境
    // ./scripts/dev.js
    const Webpack = require("webpack");
    const WebpackDevServer = require("webpack-dev-server");
    const { getDevConfig } = require("./config");
    const webpackConfig = getDevConfig();
    
    const compiler = Webpack(webpackConfig);
    const devServerOptions = Object.assign({}, webpackConfig.devServer, {
      historyApiFallback: true,
      open: true,
      hot: true,
      inline: true,
      stats: "errors-warnings",
      overlay: {
        // 浏览器全屏显示错误
        errors: true,
        warnings: false,
      },
      stats: {
        colors: true,
      },
    });
    const server = new WebpackDevServer(compiler, devServerOptions);
    
    server.listen(8087, "127.0.0.1", () => {
      console.log("Starting server on http://localhost:8087");
    });
    
    
  • 生产环境

    //使用nodeAPI构建生产环境
    // ./scripts/prod.js
    const { getProdConfig } = require("./config");
    const config = getProdConfig();
    
    const webpack = require("webpack");
    
    const compiler = webpack(config);
    
    compiler.run((err, stats) => {
      const info = stats.toJson();
    
      if (err) {
        console.error(err.stack || err);
        if (err.details) {
          console.error(err.details);
        }
        return;
      }else if (stats.hasErrors()) {
        console.error(info.errors);
      }else if (stats.hasWarnings()) {
        console.warn(info.warnings);
      }else{
          console.log('build successfully')
          console.log([
            console.log(`Time: ${info.time}ms`),
            console.log(`output: ${info.outputPath}`),
            console.log(`webpack version: ${info.version}`),
          ].join('\n'))
      }
    });
    
    
7.补充代码
  • 将webpack配置文件以函数形式封装

    // ./scripts/config/index.js
    const {
      getJSLoader,
      getVueLoader,
      getCSSLoader,
      getLESSLoader,
      getSASSLoader,
      getAssetsLoader,
    } = require("./loader");
    
    const { 
      getVueLoaderPlugin,
      getHtmlWebpackPlugin,
      getStylePlugin,
      getMiniCssExtractPlugin,
      getTerserPlugin,
      getHotModuleReplacementPlugin,
     } = require("./plugin");
    
    const { reslove } = require("./util");
    
    function getCommonConfig () {
      return {
        entry: reslove("./src/main.js"), // 入口文件
        resolve: {
          // 解析模块请求的选项
          // (不适用于对 loader 解析)
    
          extensions: [".js", ".json", ".jsx", ".css"],
          // 使用的扩展名
    
          alias: {
            // 模块别名列表
            "@": reslove("./src"),
          },
        },
      };
    }
    
    exports.getDevConfig = function () {
      const mode = "development";
    
      const common = getCommonConfig();
    
      return Object.assign(common, {
        output: {
          path: reslove("./dist"), //打包后的文件存放的地方
          filename: "[name].[hash].js", //打包后输出文件的文件名
        },
        mode,
        module: {
          // 关于模块配置
          rules: [
            // 模块规则(配置 loader、解析器等选项)
            getJSLoader(mode),
            getVueLoader(mode),
            getCSSLoader(mode),
            getLESSLoader(mode),
            getSASSLoader(mode),
            ...getAssetsLoader(mode),
          ],
        },
        plugins: [
          getVueLoaderPlugin(),
          getHtmlWebpackPlugin({
            template:reslove('./public/index.html'),
            filename:'index.html',
            minify: {
              caseSensitive: false, // 是否大小写敏感
              collapseWhitespace: true, // 是否去除空格
              removeAttributeQuotes: true, // 去掉属性引用
              removeComments: true, // 去注释
            },
          }),
          getHotModuleReplacementPlugin(),
        ],
      });
    }
    
    exports.getProdConfig = function () {
      const mode = "production";
    
      const common = getCommonConfig();
    
      return Object.assign(common, {
        output: {
          path: reslove("./dist"), //打包后的文件存放的地方
          filename: "[name].[chunkhash].js", //打包后输出文件的文件名
        },
        mode,
        module: {
          // 关于模块配置
          rules: [
            // 模块规则(配置 loader、解析器等选项)
            getJSLoader(mode),
            getVueLoader(mode),
            getCSSLoader(mode),
            getLESSLoader(mode),
            getSASSLoader(mode),
            ...getAssetsLoader(mode),
          ],
        },
        plugins: [
          getVueLoaderPlugin(),
          getHtmlWebpackPlugin({
            template:reslove('./public/index.html'),
            filename:'index.html',
            minify: {
              caseSensitive: false, // 是否大小写敏感
              collapseWhitespace: true, // 是否去除空格
              removeAttributeQuotes: true, // 去掉属性引用
              removeComments: true, // 去注释
            },
          }),
          getMiniCssExtractPlugin(),
          getStylePlugin(),
        ],
        optimization: {
          minimize: true,
          minimizer: [new getTerserPlugin()],
        },
      });
    }
    
    
  • 封装常用loaders

    // ./scripts/config/loader/index.js
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const eslintLoader = {
      loader: "eslint-loader",
      options: {
        fix: true,
      },
    };
    exports.getJSLoader = function (mode) {
      const use = [
        "thread-loader",
        {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"],
          },
        },
      ];
    
      mode === "development" && use.push(eslintLoader);
    
      return {
        test: /\.js$/,
        use,
        exclude: /node_modules/,
      };
    }
    
    exports.getVueLoader = function (mode) {
      const use = ["vue-loader"];
      mode === "development" && use.push(eslintLoader);
    
      return {
        test: /\.vue$/,
        use,
      };
    }
    
    exports.getCSSLoader = function (mode) {
      const use = [
        mode === "development" ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader",
      ];
    
      return {
        test: /\.css$/i,
        use,
      };
    }
    
    exports.getLESSLoader = function (mode) {
      const use = [
        mode === "development" ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader",
        "less-loader",
      ];
    
      return {
        test: /\.less$/i,
        use,
      };
    }
    exports.getSASSLoader = function (mode) {
      const use = [
        mode === "development" ? "style-loader" : MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader",
        "sass-loader",
      ];
    
      return {
        test: /\.less$/i,
        use,
      };
    }
    exports.getAssetsLoader = function (mode) {
    
        const name = mode === "development" ? "[name].[ext]" : "[name].[contenthash].[ext]"
    
        const imgReslove = {
            test: /\.(png|jpg|jpeg|svg|gif)$/,
            use: [
              {
                loader: "url-loader",
                options: {
                  name: `assets/images/${name}`,
                  limit: 3 * 1024,
                },
              },
            ],
          }
    
        const mediaReslove = {
            test: /\.(mp4|avi|mp3|rmvb|wmv|flv|webm)$/,
            use: [
              {
                loader: "file-loader",
                options: {
                  name: `assets/media/${name}`,
                },
              },
            ],
          }
    
        const fontReslove = {
            test: /\.(woff2|woff|eot|ttf|otf)$/,
            use: [
              {
                loader: "url-loader",
                options: {
                  name: `assets/font/${name}`,
                },
              },
            ],
          }
    
    
      return [imgReslove,mediaReslove,fontReslove];
    }
    
    
  • 封装常用plugins

    // ./scripts/config/plugins/index.js
    
    const VueLoaderPlugin = require("vue-loader/lib/plugin");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    const { HotModuleReplacementPlugin } = require('webpack');
    const TerserPlugin = require('terser-webpack-plugin');
    
    exports.getVueLoaderPlugin =  function () {
      return new VueLoaderPlugin();
    }
    
    exports.getHtmlWebpackPlugin = function (options) {
      return new HtmlWebpackPlugin(Object.assign({}, options));
    }
    
    exports.getCleanWebpackPlugin = function (options) {
      return new CleanWebpackPlugin(Object.assign({}, options));
    }
    exports.getStylePlugin = function (options) {
      return new OptimizeCssAssetsPlugin(
        Object.assign(
          {
            assetNameRegExp: /\.optimize\.css$/g,
            cssProcessor: require("cssnano"),
            cssProcessorPluginOptions: {
              preset: ["default", { discardComments: { removeAll: true } }],
            },
            canPrint: true,
          },
          options
        )
      );
    }
    exports.getMiniCssExtractPlugin = function (options) {
      return new MiniCssExtractPlugin(Object.assign({
        filename: 'assets/style/[name].[contenthash].css',
      }, options));
    }
    exports.getHotModuleReplacementPlugin = function () {
      return new HotModuleReplacementPlugin();
    }
    exports.getTerserPlugin = function (options) {
      return new TerserPlugin(
          Object.assign({
            cache: true, // 使用 cache,加快二次构建速度
            parallel: true, // 开启多线程
            extractComments: true,
            terserOptions: {
              compress: {
                unused: true,
                drop_debugger: true,
                drop_console: true,
                dead_code: true,
              },
            },
          },options)
      );
    }
    
    
  • 工具函数

    // ./scripts/config/util.js
    const path = require('path')
    
    exports.reslove = function  (url){
        return path.resolve(__dirname,`../../${url}`)
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值