使用 [email protected]+ 从0 到 1 构建一个自己的项目

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36407748/article/details/84944195

参考 webpack文档 从0到1搭建一个自己的webpack项目。网上教程很多啊,如果看完还不懂的小伙伴,希望你动手照着文档多倒腾几遍,我这个直接上的快速入门完整 demo,不是基础的概念,以及必要的依赖环境,比如node。

第一步:创建项目结构

首先我们创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):
注:不推荐全局安装,因为你可能会有不同的webpack版本的项目,如果你全局安装的话,版本就固定了,你可能处理别的不同版本的项目的时候会报错

// 创建一个文件
mkdir webpack-demo && cd webpack-demo
// 初始化一个package.json
npm init -y 
//本地化webpack 安装  开发依赖
npm i -D webpack
// 4.0以后 新加的,需要安装一个wenpack cli
npm i -D webpack-cli

初始化工作完毕(截图)
在这里插入图片描述
第二步:添加dist和src文件以及index.htm 和inde.js
在这里插入图片描述

第三步:安装 loadash 依赖和编写 js 文件
loadsh 使用处理我们的js编译的

npm install --save lodash

编写:src/index.js 文件

// 引入loadsh 
import _ from 'lodash';
function createDomElement() {
  var dom = document.createElement('div');
  //使用了loadsh 的 join() 方法,将 字符串 用 空格进行 拼接   
  dom.innerHTML = _.join(['你好', 'webpack'], '');
  return dom;
}
// 将元素添加到body里
document.body.appendChild(createDomElement());

编写 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>起步</title>
</head>
<body>
  <script src="./main.js"></script>
</body>
</html>

**第四步:编写 webpack 配置文件 webpack.config.js **
这里我新加一个config文件夹,用来放这个配置文件(因为后边还要添加开发和测试环境的配置,我这里就直接放到一个文件下了)
编写webpack.config.js(简单写了点注释)

// 引入path 模块
const path = require('path')
module.exports = {
    // 配置入口
    entry: './../src/index.js',
    // 配置环境(这里是开发)
    mode: 'development',
    // 配置出口
    output: {
        filename: 'main.js', // 文件名字
        path: path.resolve(__dirname,'../dist') // 文件路径
    }
}

最后执行

npx webpack

编译后的目录
在这里插入图片描述
在浏览器打开index.html,就看到index.js中通过loadsh的join()方法添加的字符串(这个地址栏的地址不是webpack的热加载服务,是我在vscode里起动的live-server服务,你直接浏览器打开你本地的index.html就好,我们还没有到配置热加载服务那一步,可能跟你的有点不一样)
在这里插入图片描述
下边处理非 js 模块
**第五步:加载 CSS 文件 **
-D是开发依赖, -S 是生产依赖, i是install的缩写 这里都是简写,全拼是–save -dev和–save
第一步:安装 css 和 style 模块解析的依赖 style-loader 和 css-loader

npm i -D style-loader css-loader

第二步: 添加 css 解析的 loader
修改webpack.config.js文件,添加module模块

// 引入path 模块
const path = require("path");
module.exports = {
  // 配置入口
  entry: "./../src/index.js",
  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "../dist") // 文件路径
  },
//   设置模块的处理
  module: {
    // 处理规则
    rules: [
        // 其中一条规则
      {
        test: /\.css$/, // 正则表达式,表示的意思是匹配到文件名的后缀是.css的文件
        use: ["style-loader", "css-loader"] // use就是使用这里边的loader进行处理 解析顺序是从后向前
      }
    ]
  }
};

第三步:在src文件下添加一个style文件夹,创建文件index.css,并在index.js中引入
在这里插入图片描述
在这里插入图片描述
这里重新改一下项目目录,删除了config,style文件夹让项目结构简单一些,后边再进行抽离(截图,修改后的目录),别忘记修改index.js中引入index.css的路径
在这里插入图片描述
最后再vscode的终端执行npx webpack 命令,终端快速打开快捷键
ctrl + esc下边的那个波浪线按键
刷新本地的index.html,
在这里插入图片描述
加载 Sass 文件(less不写了,同Sass配置)
第一步:安装 sass-loader node-sass

npm install sass-loader node-sass webpack --save-dev

第二步:修改webpack.js

// 引入path 模块
const path = require("path");

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {  // 设置模块的处理
    // 处理规则
    rules: [
      // 其中一条规则
      {
        test: /\.(sc|sa|c)ss$/, // 正则表达式,表示的意思是匹配到文件名的后缀是.css||sass||scss的文件
        use: ['style-loader', 'css-loader', 'sass-loader'] // use就是使用这里边的loader进行处理 解析顺序是从后向前
      }
    ]
  }
};

在src下创建一个scss文件(截图)
a.scss文件

@charset 'utf-8';
// 定义变量
$bgcolor:#f90;
$textcolor:red;
body{
    background-color: $bgcolor;
}
.box {
    color: $textcolor;
}

在这里插入图片描述
修改index.js文件,
将引入的index.css换成a.scss文件

// 引入css样式
import "./a.scss";  

执行npx webpack(颜色有点丑啊,见谅哈)
在这里插入图片描述
创建 Source Map
因为我们打包项目的时候,会把css 样式都打包到一块,这就让我们开发时不好调试,不能找到具体的某一个报错或者找到具体的某个样式所在的行数,所以使用Source Map来解决这个问题
在这里插入图片描述
上边这个截图可以看一下,你看不到你的样式具体在哪个文件下,第几行,同样你的js文件也是这样的,就不截图了下边看看Source Map怎么玩
直接修改webpack.config.js, 添加
{
loader: “css-loader”,
options: {
sourceMap: true
}
},

// 引入path 模块
const path = require("path");

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
          {
            loader: "style-loader"
          },
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  }
};

接着执行npx webpack(这样就可以看到具体的哪一行了)
在这里插入图片描述
** 处理css中自动添加浏览器前缀**
安装

npm i -D postcss-loader 
npm install autoprefixer --save-dev

修改webpack.config.js,在module属性中添加下边这个对象

// 配置postcss-loader
 {
   loader: 'postcss-loader',
   options: {
     ident: 'postcss', // 微标示浮,没有啥实际意义,官方推荐写法
     sourceMap: true,  // 启用sourceMap
     plugins: loader => [ // 插件,可以设置多个
       require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 这个是市场占有度在中国
     ]
   }
 },

在这里插入图片描述
修改a.scss,给box 添加一个display:flex属性

@charset 'utf-8';
// 定义变量
$bgcolor:#f90;
$textcolor:red;
body{
    background-color: $bgcolor;
}
.box {
    color: $textcolor;
    display: flex;
}

运行 npx webpack ,可以看到浏览器前缀自动处理了
在这里插入图片描述
样式文件单独抽离成专门的单独文件
安装
首先以下的 css 的处理我们都把 mode 设置为 production。
webpack4 开始使用: mini-css-extract-plugin插件, 1-3 的版本可以用: extract-text-webpack-plugin
抽取了样式,就不能再用 style-loader注入到 html 中了。

npm install --save-dev mini-css-extract-plugin

这里就不再修改webpack.config.js了,而是新建一个webpack.prod.js文件,(及生产环境配置)

webpack.prod.js代码:

// 引入path 模块
const path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
            MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss', // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true,  // 启用sourceMap
              plugins: loader => [ // 插件,可以设置多个
                require('autoprefixer')({ browsers: ['> 0.15% in CN'] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css', // 设置最终输出的文件名
      chunkFilename: '[id].css'
    })
  ]
};

目录截图
在这里插入图片描述
最后执行 npx webpack --config webpack.prod.js
就会看到dist 目录下多了一个main.css文件,这个时候,你需要手动把这个css文件在index.html中手动引入(截个图)
在这里插入图片描述

** CSS,js代码编译后压缩**
安装

npm i -D optimize-css-assets-webpack-plugin 
npm i -D uglifyjs-webpack-plugin

修改webpack.prod.js文件

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css", // 设置最终输出的文件名
      chunkFilename: "[id].css"
    })
    // webpack 处理css缓存,添加一个hash 
     // new MiniCssExtractPlugin({
    //     filename: '[name][hash].css', 
    //     chunkFilename: '[id][hash].css'
    // })
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};

修改index.js


// 引入loadsh 
import _ from 'lodash';
// 引入css样式
import "./a.scss";  // 需要加载loadder => css-loader  style-loader

function createDomElement() {
  var dom = document.createElement('div');
  //使用了loadsh 的 join() 方法,将字符串进行用 空格进行 拼接   
  dom.innerHTML = _.join(['你好', 'webpack'], '');
//  添加一个class
  dom.classList.add('box')
  return dom;
}
// 将元素添加到body里
document.body.appendChild(createDomElement());

执行 npx webpack --config webpack.prod.js 命令就会看到代码压缩了
在这里插入图片描述

注意:因为代码压缩我们只在线上环境时才会进行压缩,以缩小代码体积,所有要配置在开发环境中,浏览器一般都会有缓存,如果想处理混存问题,就要使用hash这个东西,同样js文件也是一样

添加别名
由于每次都运行 npx webpack --config webpack.prod.js这个指令,下边配置一下指令
打开package.json找到scripts配置,添加如下代码

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

以后就直接运行 npm run build

解决 CSS 文件或者 JS 文件名字哈希变化的问题

由于要处理浏览器缓存问题,文件名就采用了hash这种模式,但是哪次生成的都是不同的文件名,我们不可能手动去更改这个名字,就需要来处理这个问题
安装

npm install --save-dev html-webpack-plugin

修改webpack.prod.js文件

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
      chunkFilename: "[id][hash].css"
    }),
    new HtmlWebpackPlugin({
      title: "Webpack App", // 默认值:Webpack App
      filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
      template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeAttributeQuotes: true // 移除属性的引号
      }
    })
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};

现在的文件目录
在这里插入图片描述
执行npm run build,以后就自己处理打包的文件名修改了

处理dist目录
由于你每次打包项目后,你会发现每执行一次指令就会多处一个新文件,这页需要我们去处理一下,每次重新打包都先把dist文件进行清除
安装

npm install clean-webpack-plugin --save-dev

修改webpack.config.js文件

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

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

const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
      chunkFilename: "[id][hash].css"
    }),
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
      title: "Webpack App", // 默认值:Webpack App
      filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
      template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeAttributeQuotes: true // 移除属性的引号
      }
    })
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};

处理引入图片和图片压缩处理
安装 file-loader 处理文件的导入

npm install --save-dev file-loader
npm install image-webpack-loader --save-dev

修改配置文件,在module属性中的rules中添加如下代码

      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          "file-loader",
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: "65-90",
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      }

Base64处理图片
安装

npm install --save-dev url-loader

此时的 webpack.config.js 配置文件代码

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

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

const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },
      {
          // test: /\.(png|svg|jpg|gif)$/,
        test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图标库了
        use: [
          {
            loader: "url-loader", // 根据图片大小,把图片优化成base64
            options: {
              limit: 10000  // 做个限制,小于10kb进行处理
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: "65-90",
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
      chunkFilename: "[id][hash].css"
    }),
    new CleanWebpackPlugin(["dist"]),
    new HtmlWebpackPlugin({
      title: "Webpack App", // 默认值:Webpack App
      filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
      template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeAttributeQuotes: true // 移除属性的引号
      }
    })
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};

以上就是css 图片 js 等的处理,下边进行处理拆分webpack的配置,因为我们有开发,生产和和测试环境,对于相同的配置进行抽离
webpack拆分处理
webpack-merge 的工具可以实现两个配置文件的合并,这样我们就可以进行拆分文件了

安装

npm install --save-dev webpack-merge

修改项目目录
新建 webpack.common.js webpack.dev.js文件
webpack.common.js代码

// 引入path 模块
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图表库了
        use: [
          {
            loader: "url-loader", // 根据图片大小,把图片优化成base64
            options: {
              limit: 10000
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: "65-90",
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(["dist"]),
    new HtmlWebpackPlugin({
      title: "Webpack App", // 默认值:Webpack App
      filename: "main.html", // 默认值: 'index.html' 最后打包后生成的文件名
      template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeAttributeQuotes: true // 移除属性的引号
      }
    })
  ]
};

webpack.dev.js 代码

// 引入path 模块
const path = require("path");

// 引入合并
const merge = require('webpack-merge')

const common = require('./webpack.common')

let devConfig = {

  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.(sc|c|sa)ss$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },
    ]
  }
};
module.exports = merge(common, devConfig);

webpack.prod.js代码

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const merge = require('webpack-merge')

const common = require('./webpack.common')


let prodConfig = {
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },

    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
      chunkFilename: "[id][hash].css"
    }),
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};
module.exports = merge(common, prodConfig);

好了,改造完成
js 使用 source map
此功能只在开发模式下使用,添加如下代码
devtool: ‘inline-source-map’,(直接截图了)
在这里插入图片描述
你可以在index.js 故意写一段错误的代码,然后npm run build ,我这里看到如下
在这里插入图片描述

使用 webpack-dev-server 和热更新
官方的watch 监听,每次我们修改 js 或者 css 文件后,要看到修改后的 html 的变化,需要我自己重新刷新页面,这里就不介绍了。
安装

npm install --save-dev webpack-dev-server

我们只在开发阶段进行热加载及更新
webpack.dev.js修改

// 引入path 模块
const path = require("path");

// 引入合并
const merge = require('webpack-merge')

const common = require('./webpack.common')

const webpack = require('webpack');

let devConfig = {

  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  devtool: 'inline-source-map',
  devServer: {
    clientLogLevel: 'warning', // 可能的值有 none, error, warning 或者 info(默认值)
    hot: true,  // 启用 webpack 的模块热替换特性, 这个需要配合: webpack.HotModuleReplacementPlugin插件
    contentBase:  path.join(__dirname, "dist"), // 告诉服务器从哪里提供内容, 默认情况下,将使用当前工作目录作为提供内容的目录
    compress: true, // 一切服务都启用gzip 压缩
    host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问 0.0.0.0
    port: 8080, // 端口
    open: true, // 是否打开浏览器
    overlay: {  // 出现错误或者警告的时候,是否覆盖页面线上错误消息。
      warnings: true,
      errors: true
    },
    publicPath: '/', // 此路径下的打包文件可在浏览器中访问。必须是斜杠
    proxy: {  // 设置代理
      "/api": {  // 访问api开头的请求,会跳转到  下面的target配置
        target: "http://192.168.0.102:8080",
        pathRewrite: {"^/api" : "/mockjsdata/5/api"}
      }
    },
    quiet: true, // necessary for FriendlyErrorsPlugin. 启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。
    watchOptions: { // 监视文件相关的控制选项
      poll: true,   // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询. poll: true。当然 poll也可以设置成毫秒数,比如:  poll: 1000
      ignored: /node_modules/, // 忽略监控的文件夹,正则
      aggregateTimeout: 300 // 默认值,当第一个文件更改,会在重新构建前增加延迟
    }
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.(sc|c|sa)ss$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },
    ]
  },
  plugins:[
    new webpack.NamedModulesPlugin(),  // 更容易查看(patch)的依赖
    new webpack.HotModuleReplacementPlugin()  // 替换插件
  ]
};
module.exports = merge(common, devConfig);

启动: npx webpack-dev-server --config webpack.dev.js
添加npm run start 指令:
打开package.json:

    "start": "npx webpack-dev-server --config webpack.dev.js",

此时你打开,会发现浏览打开找不到文件,这个是因为
在这里插入图片描述
因为默认是index.html,这里你将main.html 修改为index.html就可以了,当然这个也是可以配置的
在这里插入图片描述

启用babel转码
安装

npm i -D babel-loader babel-core babel-preset-env

根目录下添加.babelrc 文件
.babelrc代码

{
  "presets": ["env"]
}

这里你运行npm run dev 会报错的,因为这个时候的bable是8.0以上的版本,所以配置有问题,你需要执行babel-loader的版本
npm install ‘babel-loader@7’
重新安装一下就好了
在index.js中写点es6 代码试试吧

let a = 10,
  b = 1,
  c = 2;
  console.log(a)
  console.log(b)
  console.log(c)

没有任何问题,这里已经转译过来了
在这里插入图片描述

Babel优化
安装

npm install babel-plugin-transform-runtime --save-dev
npm install babel-runtime --save

修改common.js

      {
        test: /\.js$/,
        exclude: /node_modules/, // 加快编译速度,不包含node_modules文件夹内容
        use: {
          loader: "babel-loader",
          options: {
            cacheDirectory: true,
          }
        }
      },

修改.babelrc

{
    "presets": ["env"],
    "plugins": [
      ["transform-runtime", {
        "helpers": true,
        "polyfill": true,
        "regenerator": true,
        "moduleName": "babel-runtime"
      }]
    ]
  }

resolve()解析配置别名
在common.js中

  resolve: {
    extensions: [".js", ".json"], // 默认值: [".js",".json"]
    alias: {
      "@": path.resolve(__dirname, "src/") //配置别名
    }
  },

在这里插入图片描述
eslint配置不说了
说一下扩展
比如你想引入jquery ,需要使用 externals
在这里插入图片描述
在index.html 中通过cdn引入jquery 或者npm 安装下

  <script
      src="https://code.jquery.com/jquery-3.1.0.js"
      integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
      crossorigin="anonymous"
    ></script>

在这里插入图片描述
在这里插入图片描述
打印结果
在这里插入图片描述
所有基本配置完毕,这里总结一下使用到的配置,贴一个完整的package.json

最终的package.json

{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "babel-runtime": "^6.26.0",
    "lodash": "^4.17.11",
    "postcss-loader": "^3.0.0"
  },
  "devDependencies": {
    "autoprefixer": "^9.4.2",
    "babel-core": "^6.26.3",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^7.1.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.7.0",
    "clean-webpack-plugin": "^1.0.0",
    "css-loader": "^2.0.0",
    "eslint": "^5.10.0",
    "eslint-loader": "^2.1.1",
    "file-loader": "^2.0.0",
    "html-webpack-plugin": "^3.2.0",
    "image-webpack-loader": "^4.6.0",
    "mini-css-extract-plugin": "^0.5.0",
    "node-sass": "^4.11.0",
    "optimize-css-assets-webpack-plugin": "^5.0.1",
    "sass-loader": "^7.1.0",
    "standard": "^12.0.1",
    "style-loader": "^0.23.1",
    "uglifyjs-webpack-plugin": "^2.0.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.27.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10",
    "webpack-merge": "^4.1.5"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "npx webpack-dev-server --config webpack.dev.js",
    "dev": "npx webpack --config webpack.dev.js",
    "build": "npx webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

webpack.common.js

// 引入path 模块
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
  // 配置入口
  entry: "./src/index.js",
  resolve: {
    extensions: [".js", ".vue", ".json"], // 默认值: [".js",".json"]
    alias: {
      "@": path.resolve(__dirname, "src/") //配置别名
    }
  },
  externals: {
    jquery: "jQuery"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/, // 加快编译速度,不包含node_modules文件夹内容
        loader: "babel-loader",
        options: {
          cacheDirectory: true
        }
      },
      {
        test: /\.(png|svg|jpg|gif|jpeg|ico|woff|woff2|eot|ttf|otf)$/, // 这个就是即处理图片,又处理字体图表库了
        use: [
          {
            loader: "url-loader", // 根据图片大小,把图片优化成base64
            options: {
              limit: 10000
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: "65-90",
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(["dist"]),
    new HtmlWebpackPlugin({
      title: "Webpack App", // 默认值:Webpack App
      filename: "index.html", // 默认值: 'index.html' 最后打包后生成的文件名
      template: path.resolve(__dirname, "./src/index.html"), // 使用哪个模板也就是你没有打包前用的html模板
      minify: {
        collapseWhitespace: true,
        removeComments: true,
        removeAttributeQuotes: true // 移除属性的引号
      }
    })
  ]
};

webpack.dev.js

// 引入path 模块
const path = require("path");

// 引入合并
const merge = require('webpack-merge')

const common = require('./webpack.common')

const webpack = require('webpack');

let devConfig = {

  // 配置环境(这里是开发)
  mode: "development",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  devtool: 'inline-source-map',
  devServer: {
    clientLogLevel: 'warning', // 可能的值有 none, error, warning 或者 info(默认值)
    hot: true,  // 启用 webpack 的模块热替换特性, 这个需要配合: webpack.HotModuleReplacementPlugin插件
    contentBase:  path.join(__dirname, "dist"), // 告诉服务器从哪里提供内容, 默认情况下,将使用当前工作目录作为提供内容的目录
    compress: true, // 一切服务都启用gzip 压缩
    host: '0.0.0.0', // 指定使用一个 host。默认是 localhost。如果你希望服务器外部可访问 0.0.0.0
    port: 8080, // 端口
    open: true, // 是否打开浏览器
    overlay: {  // 出现错误或者警告的时候,是否覆盖页面线上错误消息。
      warnings: true,
      errors: true
    },
    publicPath: '/', // 此路径下的打包文件可在浏览器中访问。必须是斜杠
    proxy: {  // 设置代理
      "/api": {  // 访问api开头的请求,会跳转到  下面的target配置
        target: "http://192.168.0.102:8080",
        pathRewrite: {"^/api" : "/mockjsdata/5/api"}
      }
    },
    quiet: true, // necessary for FriendlyErrorsPlugin. 启用 quiet 后,除了初始启动信息之外的任何内容都不会被打印到控制台。这也意味着来自 webpack 的错误或警告在控制台不可见。
    watchOptions: { // 监视文件相关的控制选项
      poll: true,   // webpack 使用文件系统(file system)获取文件改动的通知。在某些情况下,不会正常工作。例如,当使用 Network File System (NFS) 时。Vagrant 也有很多问题。在这些情况下,请使用轮询. poll: true。当然 poll也可以设置成毫秒数,比如:  poll: 1000
      ignored: /node_modules/, // 忽略监控的文件夹,正则
      aggregateTimeout: 300 // 默认值,当第一个文件更改,会在重新构建前增加延迟
    }
  },
  module: {
    // 设置模块的处理
    // 处理规则
    rules: [
      {
        test: /\.(sc|c|sa)ss$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },
    ]
  },
  plugins:[
    new webpack.NamedModulesPlugin(),  // 更容易查看(patch)的依赖
    new webpack.HotModuleReplacementPlugin()  // 替换插件
  ]
};
module.exports = merge(common, devConfig);

webpack.prod.js

// 引入path 模块
const path = require("path");

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const merge = require('webpack-merge')

const common = require('./webpack.common')


let prodConfig = {
  // 配置环境(这里是开发)
  mode: "production",
  // 配置出口
  output: {
    filename: "main.js", // 文件名字
    path: path.resolve(__dirname, "dist") // 文件路径(绝对路径)
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              sourceMap: true
            }
          },
          // 配置postcss-loader
          {
            loader: "postcss-loader",
            options: {
              ident: "postcss", // 微标示浮,没有啥实际意义,官方推荐写法
              sourceMap: true, // 启用sourceMap
              plugins: loader => [
                // 插件,可以设置多个
                require("autoprefixer")({ browsers: ["> 0.15% in CN"] }) // 这个是市场占有度在
              ]
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }
        ]
      },

    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name][hash].css", // webpack 处理css缓存,添加一个hash
      chunkFilename: "[id][hash].css"
    }),
  ],
  optimization: {
    minimizer: [
      new OptimizeCSSAssetsPlugin({}), // css压缩
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true // set to true if you want JS source maps
      })
    ]
  }
};
module.exports = merge(common, prodConfig);

最后的目录
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36407748/article/details/84944195