阅读 1313

webpack4.29.6搭建常用功能的环境

因项目需要,用webpack搭建一个常用功能的环境。
初步功能罗列如下:
自动配置多入口出口
less转css
css前缀自动补齐
css提取成单独文件
css压缩
图片压缩
引入字体和svg js Babel 压缩
css和js的分离/合并和过滤

1.建立并且进入文件夹

mkdir webpack4.29.6 && cd webpack4.29.6
复制代码

2.如下图建立各个demo文件和图片

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
</head>
<body>
   随便写一些index2333
</body>
</html>
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
</head>
<body>
   随便写一些about2333
</body>
</html>
复制代码

其他的文件可以先空着,图片先不导入也没关系。

3建立package.json(以下所有命令都是在webpack4.29.6文件夹下运行)

npm init -y
复制代码

4.安装以下几个依赖

(webpack/webpack-cli这两个需要注意,3.x以前版本是合并在一起的,4.x后拆分了
webpack-dev-server:起服务
html-webpack-plugin:动态生成html
webpack-merge:合并webpack配置文件)

npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-merge
复制代码

确保局部依赖和全局依赖版本都如下图是最新的(看清楚了,webpack是4.29.6的,如果你因为网络问题装成3.几的,后面将全部报错。这步很关键,不然你会有无穷尽的麻烦,如果实在不成功可以先把全局node下的webpack相关文件删除,window在c盘/Program Files/nodejs/下)。

5.建立三个webpack配置文本(1.common2.dev3.prod)并且分别写入

touch webpack.common.js webpack.dev.js webpack.prod.js
复制代码

webpack.common.js:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: {
    index: "./src/js/index.js"
  },
  output: {
    //[name] 输出名称等于输入名称   [contenthash:8] 八位hash
    filename: "[name].[contenthash:8].js",  
    //你应该知道的node path 知识: http://nodejs.cn/api/path.html
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: [
    
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "./src/index.html"
    })
  ]
};

复制代码

webpack.dev.js:

const merge = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
  mode: "development",
  //开启调试
  devtool: "source-map",
  devServer: {
    //设置基本目录结构
    contentBase: "./dist",
    //服务器的IP地址,可以使用IP也可以使用localhost
    host: "localhost",
    //服务端压缩是否开启
    compress: true,
    //配置服务端口号
    port: 8090
  }
});

复制代码

webpack.prod.js:

const merge = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
  mode: "production",
});

复制代码

6.修改下package.json中的script对象

  "scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "rimraf dist && webpack --config webpack.prod.js"
  },
复制代码

7.尝试启动服务或者打包

启动服务:

npm run dev
复制代码

打包: (rimraf dist: 打包前删除了rimraf文件夹再重新生成)

npm run build
复制代码

dist:

这样便成功了第一步。

因为修改了配置文件每步都要重启服务比较麻烦,我们这里引入nodemon。并且添加一条命令

npm install -D nodemon
复制代码

// 监听webpack.common.js文件,有变动的话就重新启动 npm run dev

"startdev": "nodemon --watch webpack.common.js --exec  npm run dev "
复制代码

package.json:

开始正式配置项目常见的功能

前面打包的文件图片可以看到只打出了index.html,这里看看怎么引入多个html

webpack.common.js: 在入口增加多一个about.js和插件多生产一个实例即可:

但是手动添加有点搓,尝试用node遍历自动导入:
在根目录新建一个multi.page.js文件:

multi.page.js:

// 多入口出口处理
const path = require("path");
const fs = require("fs");
const htmlWebpackPlugin = require("html-webpack-plugin");
const pagesPath = path.resolve("./src");

var pageList = [];
function readPages() {
  fs.readdirSync(pagesPath).forEach(e => {
    var fullPath = pagesPath + "/" + e;
    if (e.includes("html")) {
      var baseName = e.slice(0, e.indexOf("."));
      pageList.push({
        entry: pagesPath + "\\js\\" + baseName + ".js",
        chunkName: baseName,
        template: pagesPath +'\\'+ e
      });
    }
  });
  return pageList;
}

// 入口
exports.getEntryPages = function() {
  return readPages().reduce((r, page) => {
    r[page.chunkName] = page.entry;
    return r;
  }, {});
};
//出口
exports.htmlPlugins = function() {
  var list = readPages().map(page => {
    var options = {
      filename: page.chunkName + ".html",
      template: page.template,
      chunks: [page.chunkName]
    };
    return new htmlWebpackPlugin(options);
  });
  return list;
};

复制代码

webpack.common.js:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const multiPage = require("./multi.page");

module.exports = {
  //   entry: {
  //     index: "./src/js/index.js",
  //     about: "./src/js/about.js"
  //   },
  entry: multiPage.getEntryPages(),
  output: {
    //[name] 输出名称等于输入名称   [contenthash:8] 八位hash
    filename: "[name].[contenthash:8].js",
    //你应该知道的node path 知识: http://nodejs.cn/api/path.html
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: []
  },
  plugins: [
    // new HtmlWebpackPlugin({
    //   filename: "index.html",
    //   template: "./src/index.html"
    // }),
    // new HtmlWebpackPlugin({
    //   filename: "about.html",
    //   template: "./src/about.html"
    // })
    ...multiPage.htmlPlugins()
  ]
};

复制代码

就是将手动引入导出改善成nodejs自动遍历

后面就是常见功能了,先暂时写到webpack.common.js里面方便调试,最后按需切到webpack.dev.js或者webpack.prod.js

处理css(这里我以less为例)安装以下依赖

npm install -D css-loader style-loader less less-loader 
复制代码

修改webpack.common.js:

  module: {
    rules: [
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
        include: path.resolve(__dirname, "./src") // 制定路径提升性能
      }
    ]
  },
复制代码

修改index.js引入index.less,并且随意写点样式

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>test</title>
</head>
<body>
    <div class="test">
        随便写点什么 这里不要自己引入css和js 全部交给webpack来处理
    </div>
</body>
</html>
复制代码

index.js:

import index from "../css/index.less";
复制代码

index.less

body {
  display: flex;
  background: #666;
  .test {
    color: #ff0;
  }
}
复制代码

就会发现相关样式在head style 里了
再优化一步,将style提出来
安装依赖mini-css-extract-plugin

npm install -D mini-css-extract-plugin
复制代码

webpack.common.js 引进依赖、修改规则和产出,文件总体如下

webpack.common.js:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const multiPage = require("./multi.page");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //提取css文件

module.exports = {
  //   entry: {
  //     index: "./src/js/index.js",
  //     about: "./src/js/about.js"
  //   },
  entry: multiPage.getEntryPages(),
  output: {
    //[name] 输出名称等于输入名称   [contenthash:8] 八位hash
    filename: "[name].[contenthash:8].js",
    //你应该知道的node path 知识: http://nodejs.cn/api/path.html
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        // use: ["style-loader", "css-loader", "less-loader"],
        use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
        include: path.resolve(__dirname, "./src") // 制定路径提升性能
      }
    ]
  },
  plugins: [
    // new HtmlWebpackPlugin({
    //   filename: "index.html",
    //   template: "./src/index.html"
    // }),
    // new HtmlWebpackPlugin({
    //   filename: "about.html",
    //   template: "./src/about.html"
    // })
    ...multiPage.htmlPlugins(),
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:8].css"
    })
  ]
};

复制代码

继续优化将css前缀自动补齐

安装依赖:

npm install -D postcss-loader autoprefixer
复制代码

修改package.json:

  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
复制代码

修改webpack.common.js:

--- use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
+++  use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "postcss-loader",
            options: {
              plugins: () => [require("autoprefixer")()]
            }
          },
          "less-loader"
        ],
复制代码

最后压缩css文件

安装依赖:

npm install -D optimize-css-assets-webpack-plugin
复制代码

修改webpack.common.js:

const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')


new OptimizeCssAssetsPlugin({
    assetNameRegExp: /\.css$/g, 
    cssProcessor: require('cssnano'), //用于优化\最小化CSS的CSS处理器,默认为cssnano
    cssProcessorOptions: { safe: true, discardComments: { removeAll: true } }, //传递给cssProcessor的选项,默认为{}
    canPrint: true                    //一个布尔值,指示插件是否可以将消息打印到控制台,默认为true
}),
复制代码

查看一下结果 源文件:

打包后的:

另外补充一句,看到头部这里莫名其妙引入了一个这个style和相关样式,一脸懵逼还未找到问题所在。

引入图片以及对图片进行压缩

npm install -D css-loader file-loader html-withimg-loader image-webpack-loader
复制代码

webpack.common.js:

{
        test: /\.(svg|png|jpe?g|gif)$/i,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 1,
              name: "images/[name].[contenthash:8].[ext]",
              publicPath: "../"
            }
          },
           {
            loader: "image-webpack-loader",
            options: {
              pngquant: {
                quality: "70-80",
                speed: 1
              }
            }
          }
        ]
      },
      {
        test: /\.html$/,
        use:[
            'html-withimg-loader'
        ]
      }
复制代码

引入字体

修改webpack.common.js:

      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "assets/[name].[contenthash:8].[ext]",
              publicPath: "../"
            }
          }
        ]
      }

复制代码

babel 升级后有点小恶心..不想说了 后面再根据项目丰富css和js的提取和合并过滤

from:webpack.docschina.org/api/

文章分类
前端
文章标签