22种webpack常用配置

689 阅读13分钟

1.下载Node.js

进入官网 nodejs.cn/download/

选择对应的版本

win+r输入cmd打开命令行

输入node -v,显示版本则安装成功

D:\git-Warehouse\webpackDemo>node -v
v12.10.0

2.初始化项目

首先创建一个新目录

进入新目录里面

在当前目录下打开命令行窗口

输入 npm init

一路回车下去就行了

此时目录里面多了一个文件package.json

内容如下

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

3.安装Webpack

还是当前目录,执行命令

npm i webpack webpack-cli  -D

此时目录如下

在命令终端使用npm i安装依赖关系时

如果带后缀 -D(或–save-dev) 安装的包会记录在"devDependencies"下;

如果使用 --save后缀(我们后面会用到)安装的包会记录在"dependencies"下。

两者的区别是:

“devDependencies”:dev开发时的依赖包

dependencies:程序运行时的依赖包

在此目录下创建一个src目录

进入scr目录,创建一个index.js文件

简单写个代码,比如

console.log("Hello, word")

切换到命令行

执行以下代码

npx webpack src/index.js

此时发现项目根目录下多了一个dist目录

在此目录下创建一个index.html,引入dist目录下的main.js

出现以下结果,打包成功

4.配置webpack

新建build目录

创建webpack.config.js文件

在里面添加以下配置

var webpack = require("webpack");
var path = require("path");
var DIST_PATH = path.resolve(__dirname, '../dist');
module.exports = {
    entry: path.resolve(__dirname, "../src/index.js"),
    output: {
     path: DIST_PATH,       // 创建的bundle生成到哪里  
      filename: 'bundle.js', // 创建的bundle的名称
    },    
    module: {
    },
    plugins: [],
    devServer: {
    }
}

其中各项作用为

entry:入口JS路径,指示Webpack应该使用哪个模块,来作为构建其内部依赖图的开始

output: 编译输出的JS入路径,告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件

module:模块解析

plugins:插件

devServer:服务器配置

回到package.json文件

添加以下代码

"scripts": {
"build": "webpack --config ./build/webpack.config.js --mode production", 
"test": "echo \"Error: no test specified\" && exit 1" 
}

这样我们可以不用输入

npx webpack src/index.js --output dist/bundle.js --mode none

直接用npm run build代替

其中“–mode production”表示项目的环境,不配置这个会报警告

输入npm run build重新打包

目录下多了一个我们自己定义的bundle

5.配置server服务

找到刚才编写的webpack.config.js,添加以下代码

  devServer: {
        hot: true, // 热更新,无需手动刷新 contentBase: DIST_PATH, 
        // host: '0.0.0.0', // host地址
        port: 8080, // 服务器端口 
        historyApiFallback: true,// 该选项的作用所用404都连接到index.html 
        proxy: {
            "/api": "http://localhost:3000" // 代理到后端的服务地址,会拦截所有以api开头的请求地址
        }
    }

和build类似,需要在package.json的scripts中添加相关的命令

在package.json中

  "scripts": {
        "build": "webpack --config ./build/webpack.config.js --mode production",
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --config ./build/webpack.config.js --mode development --open"
    },

安装webpack-dev-server

npm i  webpack-dev-server -D

运行npm run dev,打开localhost:8080,就可以看见网站

注意!!!!

开发不能设置output的publicPath,否则页面出不来,因为找不到路径,使用默认的就好了

可以如下设置

判断当前环境

const devMode = process.env.NODE_ENV === 'production'

动态publicPath

 output: {
        // 编译输出的JS入路径 
        // 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
        path: DIST_PATH,   // 创建的bundle生成到哪里  
        filename: 'js/[name].js', // 创建的bundle的名称
        publicPath: devMode ? './' : "",
    },

现在还不能直接运行,得安装一个插件

6.自动生成index.html

安装插件

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

首先引入我们的插件

let HtmlWebpackPlugin = require('html-webpack-plugin');

在配置文件中添加

plugins: [
     new HtmlWebpackPlugin(),
   ],

同时,HtmlWebpackPlugin方法里可以接受一个对象, 如指定模板文件

new HtmlWebpackPlugin({
            template: "./src/index.html"
        })

此时打包生成的网页文件,除了你webpack中绑定的数据,还有你模板中的代码

打开命令行,输入npm run dev

demo地址 github.com/ZengHaiTao1…

7.生成前先清楚dist文件夹

安装对应插件

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

在配置文件中引入插件

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

添加在配置文件最前面

 plugins: [
     new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
        title: 'Output Management',
      }),
    ],

8.加载css

8.1.安装所需要的模块

npm install --save-dev css-loader
npm install --save-dev style-loader

8.2.在webpack.config.js配置文件中配置module

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

其中‘style-loader’一定要写在前面

8.3.options选项

module: {
        rules: [ //配置加载器, 用来处理源文件, 可以把es6, jsx等转换成js, sass, less等转换成css
            {
                test: /\.css$/, //配置要处理的文件格式,一般使用正则表达式匹配
                use: [
                    {
                        loader: "style-loader"
                    },
                    {
                        loader: "css-loader",
                        options: {
                            modules: true, // 指定启用css modules
                        }
                    }
                ]
            }
        ]
    },

9加载scss

安装对应的解析器

npm install sass-loader node-sass --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
      }]
    }]
  }
};

就可以正常使用scss文件了

测试css

在src目录下新建static目录,创建css目录,index.css文件

定义背景色

在index.jsyin

输入npm run dev 打开 网页

测试scss

修改后缀名

修改配置文件

  module: {
        rules: [{
            test: /\.scss$/,
            use: [{
                loader: "style-loader" // 将 JS 字符串生成为 style 节点
            }, {
                loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
            }, {
                loader: "sass-loader" // 将 Sass 编译成 CSS
            }]
        }]
    },

启动项目,正常运行。

代码地址 github.com/ZengHaiTao1…

10.加载图片

npm install file-loader --save-dev

配置模块加载器


 {
                test: /\.(png|jpe?g|gif)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        // options: {
                        //     name(file) {
                        //         if (process.env.NODE_ENV === 'development') {
                        //             return '[path][name].[ext]';
                        //         }
                        //         return '[name].[ext]';
                        //     },
                        //     outputPath: 'images',
                        // }
                    },
                ],
            },

图片的使用方法

1.在主页中

直接引入打包后的路径

<img src="'xxx.jpg'"/>

2.在模板页中,模板页里的img 标签中相对路径的图片不会被loader 解析,因此需要使用require 引用图片

<img src="${require('xxx.jpg')}"/>

11.配置url-loader

安装解析器

npm install url-loader --save-dev
{
                test: /\.(png|svg|jpg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: 'images/[name].[ext]',
                        limit: 1024
                    }
                }
 },

12.优化Webpack配置

在build文件夹下创建三个文件

公共配置:把开发和生产环境需要的配置都集中到公共配置文件中,即webpack.common.js

开发环境配置:把开发环境需要的相关配置放置到webpack.dev.js

生产环境配置:把生产环境需要的相关配置放置到webpack.prod.js

为了更好的管理和维护这三个文件,需要安装一个webpack-merge插件:

npm i webpack-merge -D

在公共配置文件webpack.common.js文件中添加相应的配置

const webpack = require('webpack');
const path = require('path');
const DIST_PATH = path.resolve(__dirname, '../dist/'); // 声明/dist的路径 
module.exports = {

    // 入口JS路径 
    // 指示Webpack应该使用哪个模块,来作为构建其内部依赖图的开始 

    entry: path.resolve(__dirname, '../src/index.js'), // 编译输出的JS入口路径

    // 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件 
    output: {
        path: DIST_PATH, // 创建的bundle生成到哪里 
        filename: 'main.js', // 创建的bundle的名称 
    },
    // 模块解析 
    module: {},
    // 插件
    plugins: []

}

接着给Webpack开发环境配置文件webpack.dev.js添加下面的相关配置:

const webpack = require('webpack'); 
const path = require('path'); 
const merge = require('webpack-merge'); 
const commonConfig = require('./webpack.common.js');
const DIST_PATH = path.resolve(__dirname, '../dist/'); // 声明/dist的路径
 module.exports = merge(commonConfig, { 
mode: 'development', // 设置webpack mode的模式
// 开发环境下需要的相关插件配置
plugins: [ ],
// 开发服务器
devServer: { 
hot: true, // 热更新,无需手动刷新 
contentBase: DIST_PATH,
// host: '0.0.0.0', // host地址
port: 8080, // 服务器端口 
historyApiFallback: true, // 该选项的作用所用404都连接到index.html
proxy: { 
// 代理到后端的服务地址,会拦截所有以api开头的请求地址
"/api": "http://localhost:3000"
} }
})

继续给Webpack生产环境配置文件webpack.prod.js添加相关配置:

const webpack = require('webpack'); 
const path = require('path'); 
const merge = require('webpack-merge'); 
const commonConfig = require('./webpack.common.js');
module.exports = merge(commonConfig, {
		mode: 'production', // 设置Webpack的mode模式 
		// 生产环境下需要的相关插件配置 
		plugins: [ ], 
})

同时,我们要修改package.json中的scripts中的信息

"scripts": {
"build": "webpack --config ./build/webpack.prod.js --mode production", 
"dev": "webpack-dev-server --config ./build/webpack.dev.js --mode development --open", "test": "echo \"Error: no test specified\" && exit 1" },

13.使用source map功能, 跟踪源文件错误

正常我们编译的js代码报错是直接显示报错信息的,是编译之后的出错位置,不显示源文件中哪里出错,不利于我们调试

我们可以在配置文件中配置devtool来解决这一问题

设置devtool

1、source-map:产生文件,产生行列

2、eval-source-map:不产生文件,产生行类

3、cheap-source-map:产生文件,不产生列

4、cheap-module-eval-source-map:不产生文件,不产生列

更多选项可查看官网devtool配置 webpack.js.org/configurati…

在本地调试时,我们可以设置为devtool: ‘inline-source-map’,

用于说明性目的(但不适合制作)。

14 从js中分离css

安装插件

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

修改配置文件

{
                test: /\.(sa|sc|c)ss$/,  // 可以打包后缀为sass/scss/css的文件
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        },
                    },
                    {
                        loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
                    }, {
                        loader: "sass-loader" // 将 Sass 编译成 CSS
                    }
                ],
            },

使用插件

 new MiniCssExtractPlugin({
            // 这里的配置和webpackOptions.output中的配置相似
            // 即可以通过在名字前加路径,来决定打包后的文件存在的路径
            filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
            chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
        }),

最基础的配置就完成了

现在根据运行环境动态配置

const devMode = process.env.NODE_ENV !== 'production'

在MiniCssExtractPlugin.loader模块解析中添加选项

publicPath公共输出目录

如下

publicPath: devMode ? '../' : './',   // 根据不同环境指定不同的publicPath
 hmr: devMode, // 仅dev环境启用HMR功能

一般打包后路径出现问题,就与这个路径有关

同时在我们的插件配置里

filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',

15.多页面开发

1.在src目录下创建文件夹page1,page2

2.修改配置文件入口

 entry: {
        main1: path.resolve(__dirname, "./src/page1/index.js"),
        main2: path.resolve(__dirname, "./src/page2/js/main2.js"),
    },

3.修改出口

 output: {
        // 编译输出的JS入路径 
        // 告诉Webpack在哪里输出它所创建的bundle,以及如何命名这些文件
        path: DIST_PATH,   // 创建的bundle生成到哪里  
        filename: 'js/[name].js', // 创建的bundle的名称
        publicPath: '../',
    },

其中注意filename不能固定死!

3.修改HtmlWebpackPlugin插件配置

new HtmlWebpackPlugin({
            filename: __dirname + '/dist/page1/index.html',
            template: __dirname + "/src/page1/index.html",
            chunks: ['main1'],
            inlineSource: '.(js|css)$'
        }),
new HtmlWebpackPlugin({
            filename: __dirname + '/dist/page2/index.html',
            template: __dirname + "/src/page2/index.html",
            chunks: ['main2'],
            inlineSource: '.(js|css)$'
        }),

chunks中写你页面所依赖的输出配置文件

到这里,一个简单的单页面配置就完成了。

16.分离公共css,js

使用SplitChunksPlugin

这个webpack 4+ 版本已经内置

修改配置文件,加入以下代码

optimization: {
        splitChunks: {
            cacheGroups: {
                //打包公共模块
                commons: {
                    chunks: 'initial', //initial表示提取入口文件的公共部分
                    minChunks: 2, //表示提取公共部分最少的文件数
                    minSize: 0, //表示提取公共部分最小的大小
                    name: 'commons' //提取出来的文件命名
                }
            }
        }
    }

同时,我们要修改HtmlWebpackPlugin 插件,将所提取出来的commons注入到页面中去

chunks: ['main1', "commons"],

17.使用glob动态配置入口

安装glog

npm install glob -save-dev  

glob可以用来匹配路径

var glob = require("glob")
// options is optional
glob("**/*.js", options, function (er, files) {
  // 文件是文件名数组。
  // 如果设置了`nonull`选项,则什么也没有
  // 被发现,则文件为[“ ** / *。js”]
  // er是错误对象或null。
})

第一个参数可以用以下方式匹配

在路径部分中使用下列字符具有特殊的神奇含义:
*匹配单个路径部分中的0或多个字符。
?匹配1字符
[...]匹配一系列字符,类似于RegExp范围。如果范围的第一个字符是!^然后它匹配任何不在范围内的字符。
!(pattern|pattern|pattern)匹配任何不匹配提供的任何模式。
?(pattern|pattern|pattern)匹配所提供的模式的零或一次。
+(pattern|pattern|pattern)匹配一个或多个提供的模式。
*(a|b|c)匹配所提供的模式的零次或更多次。
@(pattern|pat*|pat?erN)与所提供的模式之一完全匹配。
**如果“珠星”单独存在于路径部分,则匹配零个或多个目录和搜索匹配的子目录。它不爬行符号链接目录。

*和**的使用方法


glob("./src/components/**/*.js", function (er, files) {
    console.log(files);
    return files
});
// [ './src/components/index/index.js',
//    './src/components/news/n.js',
//    './src/components/news/news.js' ]

?的使用方法

glob("./src/components/**/?.js", function (er, files) {
    console.log(files);
    return files
});
//[ './src/components/news/n.js' ]

有几个“?”就匹配几个字符

[…]的使用方法

glob("./src/components/**/inde[a-z].js", function (er, files) { console.log(files) }) //[ './src/components/index/index.js' ]

匹配满足[a-z]条件的路径,相比?方法匹配更为精准一些

?()的使用方法

glob("./src/components/**/?(news|index|n).js", function (er, files) {
    console.log(files)
});
// [ './src/components/index/index.js',
//     './src/components/news/n.js',
//     './src/components/news/news.js' ]

+()的使用方法


glob("./src/components/**/+(in|news|dex).js", function (er, files) {
    console.log(files)
});
// [ './src/components/index/index.js',
//     './src/components/news/news.js' ]

本案例中会匹配in.js,news.js,dex.js,innews.js,index.js,newsdex.js 他会先匹配自身是否会匹配上,然后在和其他模式组合在进行匹配。

@()的使用方法

他会完整匹配备选模式中的其中一个,只要有一个模式匹配上就会被匹配

glob("./src/components/**/@(index|n|news).js", function (er, files) {
    console.log(files)
});
// [ './src/components/index/index.js',
//     './src/components/news/n.js',
//     './src/components/news/news.js' ]

!()的使用方法,理解为反的意思,其实这个没什么说的, 稍微懂点js的都会。和运算表达式中的!一样。

案例中的意思是不要n.js 不要index.js,所以就只剩下new.js了。

glob("./src/components/**/!(n|index).js", function (er, files) {
    console.log(files)
})
// [ './src/components/news/news.js' ]

在上述案例中使用的都是异步请求,调用回调得到结果,其实glob也提供了同步返回结果的API ,在这里我只列举一个。

let pattern = './src/components/**/@(index|n|news).js';
console.log(glob.sync(pattern));
// [ './src/components/index/index.js',
//     './src/components/news/n.js',
//     './src/components/news/news.js' ]
const glob = require("glob")

匹配路径


const htmls = glob.sync("src/page?/page?.js")

我的目录结构为

所以匹配到的是

src/pagea/pagea.js
src/pageb/pageb.js

接着定义一个 entrys对象,定义一个 htmlCfg数组,htmlCfg数组添加到插件解析上

htmls.forEach(filePath => {    // "src/page1/page1.js"
    let path = filePath.trim().split('/'); //分割路径, ['src', 'page1', 'page1.js'], 放进 path 数组里
    let file = path.pop();   //'page1.js'
    let name = file.split(".")[0];  //page1
    entrys[name] = "./" + filePath
    htmlCfgs.push(
        new HtmlWebpackPlugin({
            template: "./src/" + name + "/" + name.trim() + ".html",  //  "./src/page1/page1.html"
            chunks: ["./dist/" + name, 'commons'],
            filename: name + ".html",
            inlineSource: '.(js|css)$'
        })
    )
});

调用js函数获取文件名,以及所需要的路径,如上

接着修改配置文件

将entrys和htmlCfg加在配置文件中

entry: entrys,
   plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            // 这里的配置和webpackOptions.output中的配置相似
            // 即可以通过在名字前加路径,来决定打包后的文件存在的路径
            filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
            chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
        }),
    ].concat(htmlCfgs)

18.使用babel解析es6语法

bael是什么

Babel 是一个让我们能够使用 ES 新特性的 JS 编译工具,我们可以在 webpack 中配置 Babel,以便使用 ES6、ES7 标准来编写 JS 代码。 Babel是JavaScript编译器 Babel是一个工具链,主要用于在当前和较旧的浏览器或环境中将ECMAScript 2015+代码转换为JavaScript的向后兼容版本。以下是Babel可以为您做的主要事情:

// Babel Input: ES2015 arrow function
[1, 2, 3].map((n) => n + 1);

// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
  return n + 1;
});

安装babel-loader 和 @babel/core

npm i -D  babel-loader
npm i -D  @babel/core

配置babel-loader模块解析

 {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: { loader: 'babel-loader' } // options 在 .babelrc 定义
      }

打开我们的js入口文件,编写es6代码

const func = () => {
    console.log('hello webpack')
}
func()

class User {
    constructor() {
        console.log('new User')
    }
}

const user = new User()

在配置文件中添加

mode: "development",

因为webpack4已经为我们配置了css,js代码压缩,默认生产环境开启

此时打包项目

发现es6语法,并没有转换

安装@babel/preset-env

这个包包含了 es6+ 的语法转换规则,如箭头函数、const 等

同时我们安装@babel/polyfill

这个包可以让我们使用es6 内置对象和函数的垫片,如 Promise、Array.from 等

安装完之后,在根目录下创建 .babelrc 文件,进行一些简单配置:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}

在babel7的版本我们可以采用babel.config.js进行配置

// babel.config.js

module.exports = function (api) {
    api.cache(true)

    const presets = [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage"
            }
        ]
    ]
    const plugins = [
        [
            "@babel/plugin-transform-runtime",
            {
                "corejs": 2
            }
        ]
    ]

    return {
        presets,
        plugins
    }
}

看网上说要在入口js文件中加上import ‘@babel/polyfill’

我试了一下 不加可以正常解析

大概是版本的问题吧。

打包后发现,Js文件过大,把一些不需要的语法也打包进来了

此时我们修改.babelrc文件

useBuiltIns: “usage”, “entry”, “false”。默认为 false。

usage: 在每个文件中使用 polyfill 时,为 polyfill 添加特定导入,babel 利用捆绑器只加载一次相同的polyfill。

entry: 使用 entry 属性,必须在项目入口处引入一次 @babel/polyfill。然后 babel 在做代码转换的时候,会把

将 .babelrc 下的useBuiltIns改为usage,再执行转换命令,就会发现 polyfill 变成了按需导入。

** babel 7 还提供了targets,这个配置主要用于指定需要支持的环境,一般是指浏览器版本。( targets 还可以指定 node、android、ios、electron 等其他环境)**

设置了 targets,babel 在转换前,会先检查 targets 指定的环境已经支持了哪些新语法和 API,然后就不再转换或者不引入已经支持的内容。

@babel/plugin-transform-runtime、@babel/runtime

使用 @babel/polyfill 会对全局对象进行污染,所以可以使用 @babel/plugin-transform-runtime 和@babel/runtime 防止这种现象。

@babel/plugin-transform-runtime 会在你需要的地方自动引入你使用到的新方法。

修改 .babelrc 文件:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage"
            }
        ]
    ],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            {
                "corejs": 2
            }
        ]
    ]
}

看了上面的做法,你可能会觉得困惑,为什么要一起使用 @babel/plugin-transform-runtime、@babel/runtime 呢,为什么不能单独使用一个?

其实是因为 babel 转换时,@babel/plugin-transform-runtime 这个插件会自动引入使用到的新方法,而引入的这些 polyfill 包是在 @babel/runtime 里面的,所以 @babel/runtime 需要安装在 dependency(生产环境)下,@babel/plugin-transform-runtime 则安装在 devDependency(开发环境)下。

同时,博主运行的时候报错,找不到"@babel/runtime-corejs2": "^7.7.5"模块

最后安装**@babel/runtime-corejs2": "^7.7.5**,配置到这里就结束了。

19.引入第三方库的三种方法

1.通过html页面script标签引入

通常是采用CDN

<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>.js

//网上说要配置这么一段,我试过了好像不用,先贴上来,你们可以尝试一下
// 入口文件
import $ from 'jquery'
console.log($)

//webpack配置
module.exports = {
    externals: {
        jquery: 'jQuery'
    }
}

在html文件中引入了之后,就可以在入口文件(app.js)中,使用 $(function(){}) 了

2.通过NPM包引入

以jq为例子

 npm install jquery --save;

然后我们在配置文件中配置

plugins:[
        new webpack.ProvidePlugin({
            $:"jquery",    //这里的意思是就把 $ 注入模块中 , 而后面的jquery 就是node_modules目录下的jquery
        })
    ]

同时我们可以将第三方库分离出来

optimization: {
        splitChunks: {
            chunks: "all", // async表示抽取异步模块,all表示对所有模块生效,initial表示对同步模块生效
            cacheGroups: {
                //打包公共模块
                // vendors: { // 键值可以自定义
                //     //chunks: 'initial',  //initial表示提取入口文件的公共部分
                //     minChunks: 1, // 代码块至少被引用的次数
                //     test: /[\\/]node_modules[\\/]/,
                //     name: "vendors", // 入口的entry的key
                //     // enforce: true   // 强制 
                //     // priority: -10   //抽取优先级
                // }
            }
        }
    },

配置完成后所有通过npm引入的第三方库将被打包成vendors.js,没有使用过的第三库不会被打包

3.引入本地第三方库

这种也是网上最少的一种,博客花了三个小时左右才真正解决问题,网上大多都是讲npm引入,或者就是本地引入方法出问题

简单说一下

第一种。

通入入口文件引入

entrys["vendors"] = ["./src/lib/jquery-3.2.1.js"]

一定要把使用的库放在前面

然后在HtmlWebpackPlugin插件中配置

 chunks: ["vendors", name, 'commons',],

缺点:不管有没有使用,都会被打包进js文件

第二种

直接在入口js通过路径引入

import "./../lib/jquery-3.2.1.js"

然后就可以使用了

看到这里,小伙伴们可能会疑问

这样的话为什么不直接定义个webpack.ProvidePlugin和通过NPM包引入引入一样了

试过

我先配置了模块别名

 resolve: {
        alias: {
            // vue$: path.resolve(__dirname, "./src/lib/vue.js"),
            // vue: path.resolve(__dirname, "./src/lib/qqq.js"),
            // jquery: path.resolve(__dirname, "./src/lib/jquery-3.2.1.js"),
        }
    },

然后和npm包引入一样的方法

 new webpack.ProvidePlugin({
            // $: 'jquery',
            // jQuery: 'jquery',
            // "window.$": 'jquery',
            // "window.jQuery": 'jquery',
})

结果控制台报错,$没有定义,然后我又安装了expose-loader,试图把JQ抛出到全局变量

配置如下

//     test: require.resolve(path.resolve(__dirname, "./src/lib/jquery-3.2.1.js")),
            //     use: [{
            //         loader: 'expose-loader',
            //         options: 'jQuery'
            //     }, {
            //         loader: 'expose-loader',
            //         options: '$'
            //     }]
            // },

结果依然显示没有定义

再后来博主通过imports-loader将模块直接导入入口js文件

 // {
            //     test: path.resolve(__dirname, "./src/pagea/pagea.js"),
            //     exclude: /node_module/,
            //     use: [{
            //         loader: "imports-loader",
            //         options: {
            //             $: 'jquery',
            //             jquery: 'jquery'
            //         }
            //     }
            //     ]
            // },

依然是提示,$没有定义,以上情况,JQ均打包进了js文件中,切在文件顶部

博主在引入本地第三方库上花了大量时间,

总结,能用npm引入就用npm引入,不能使用npm引入的第三方库,可以采用上面两种方法引入 能用谷歌就用谷歌,百度了一大堆,能看的,能用的就那么两三个。

20.删除没有使用过的css代码

安装依赖

npm i -D purifycss-webpack purify-css

修改配置文件

new PurifyCSSPlugin({
      // Give paths to parse for rules. These should be absolute!
      paths: glob.sync(path.join(__dirname, './src/**/*.html')),
    })

21.自动添加css前缀

webpack打包时,css自动添加浏览器前缀。我们需要用到一个Loader:postcss-loader,和一个插件:autoprefixer

npm i -D postcss-loader autoprefixer

配置解析器

{
                test: /\.(sa|sc|c)ss$/,  // 可以打包后缀为sass/scss/css的文件
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            // 这里可以指定一个 publicPath
                            // 默认使用 webpackOptions.output中的publicPath
                            // publicPath的配置,和plugins中设置的filename和chunkFilename的名字有关
                            // 如果打包后,background属性中的图片显示不出来,请检查publicPath的配置是否有误
                            // publicPath: './',
                            publicPath: devMode ? '../' : './',   // 根据不同环境指定不同的publicPath
                            hmr: devMode, // 仅dev环境启用HMR功能
                        },
                    },
                    {
                        loader: "css-loader" // 将 CSS 转化成 CommonJS 模块
                    }, {
                        loader: "sass-loader" // 将 Sass 编译成 CSS
                    }, {
                        loader: "postcss-loader"
                    }
                ],
            },

把**“postcss-loader”**放在最后

然后在webpack.config.js文件同级目录中,新建postcss.config.js文件,并且添加如下代码:

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

同时我们也可以不创建postcss.config.js配置文件,直接在主配置文件中引入

{
                        loader: "postcss-loader",
                        options: {
                            plugins: [
                                require('autoprefixer')//postcss-loader会叫autoprefixer插件添加浏览器前缀
                            ]
                        }
                    }

使用tx-loader解析typescript

npm install --save-dev typescript
npm install --save-dev ts-loader
{
    "compilerOptions": {
        "outDir": "./dist/",
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es6",
        "allowJs": true,
        "sourceMap": true
    }
}

配置解析器


 resolve: {
        extensions: [".ts", ".tsx", ".js"]
    },
     {
                test: /\.ts|.tsx$/,
                exclude: [
                    path.resolve(__dirname, 'node_modules'),
                ],
                use:
                {
                    // loader: 'ts-loader',
                    loader: 'ts-loader',
                },
            },

然后就可以在项目中正常使用typeScript了

使用babel解析typescript

npm install --save-dev @babel/preset-typescript

修改babel.config.js配置文件 babel7之后可以使用babel.config.js作为配置文件

// babel.config.js

module.exports = function (api) {
    api.cache(true)

    const presets = [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage"
            }
        ],
        [
            '@babel/preset-typescript',
            {
                allExtensions: true,        // 支持所有文件扩展名
            },
        ],

    ]
    const plugins = [
        [
            "@babel/plugin-transform-runtime",
            {
                "corejs": 2
            },
            "transform-typescript"
        ]
    ]

    return {
        presets,
        plugins
    }
}

修改webpack配置文件,模块解析

{
                test: /\.ts|.tsx$/,
                exclude: [
                    path.resolve(__dirname, 'node_modules'),
                ],
                use:
                {
                    // loader: 'ts-loader',
                    loader: 'babel-loader',
                },
            },

22.使用pug模板

pug是什么

Pug是一款健壮、灵活、功能丰富的HTML模板引擎,专门为 Node.js 平台开发。Pug是由Jade 改名而来。

是一种通过缩进(表示标签间的嵌套关系)的方式来编写代码的过程,在编译的过程中,不需要考虑标签是否闭合的问题。可以加快写代码速度,也为代码复用提供了便捷。

类别的话,可以理解为,scss,typescript,这种需要编译的,编程式语言

安装依赖

npm install pug pug-html-loader raw-loader --save-dev

配置解析

 {
        test: /\.pug$/,
        loader: ["raw-loader", 'pug-html-loader']
    ,
}

在vscode中配置pug模板

"Pug": {
"prefix": "pug",
"body": [
"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 Document",
      "body"
],
"description": "pug"
}