Webpack包教不包会

Webpack是什么?

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。 ——Webpack文档

简单来说 Webpack就是一个前端项目的打包工具,精简一下就是:Webpack就是个工具

WebPack打包方式有什么特点?

WebPack以JavaScript为入口(entry);通过不同的loader,处理不同格式的资源(file资源file-loader/url-loader,css资源style-loader/css-loader,JavaScript资源babel-loader,等);通过html-webpack-plugin动态生成html文件并插入CSS、JavaScript资源;通过output配置已经处理过的文件,包括文件的名称(filename)、生成文件放置位置(path)、线上资源服务路径(publicPath),非入口文件名称(chunkFilename)等。

WebPack的常用配置是什么?

  • entry WebPack的入口,打包入口文件的配置
  • output Webpack的出口,输出打包后的文件配置
  • mode 配置的模式 development (开发模式) / production(生产模式) / none
  • module 模块的处理方式 在这里使用各种loader处理不同的资源
  • plugins WebPack常用的一些插件 包括动态生成Html,将CSS生成文件等等
  • devtool 调试方式 source-map等,
  • resolve 设置模块如何被解析 alias 地址简写 extensions 后缀自动查找等
  • context: 基础目录,绝对路径,用于从配置中解析入口起点(entry point)和 loader

WebPack的entry配置有几种常用方式?

1 './index.js'
2 {
     index: './index.js'
 }
3 ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true', './index.js']
4 {
    index: ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true',
    , './index.js']
}

第二种常在打包生成上线文件时使用,第四种模式在多页面需要进行HMR时,
第三种模式在进行SPA页面开发时,或者在优化多页面HMR过程,HtmlWebpackPlugin生成Html文件比较耗时,这时可以专注于当前开发的页面,即只打包当前开发的页面,减少需要重新生成的文件。

WebPack的output配置有几种参数?

 output: {
        filename: 'static/[name].js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        chunkFileName: ''
    }

filename: 文件名称 可以类似static/[name].js这样书写,可以增加一个static文件夹
path 输出的路径
publicPath 服务器防止资源文件的路径
chunkFileName 非入口文件
WebPack的mode配置有几种设置?

production development none

如果不设置,按照production方式

WebPack的常用module怎么配置?

module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        // you can specify a publicPath here
                        // by default it uses publicPath in webpackOptions.output
                        hmr: process.env.NODE_ENV === 'development',
                    },
                },
                'css-loader'
            ]
        },
        {
            test: /\.(png|jpg|gif|svg)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'images',
                    }
                }
            ]
        },
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'fonts'
                    }
                }
            ]
            {
            test: /.html$/,
            loader: [
                'html-loader'
            ]
        }
        }
    ]
}

还有bable-loader ,url-loader, postcss-loader,less-loader,vue-loader,sass-loader等等

WebPack的怎么动态生成html并插入资源文件(css,js)?

return new HtmlWebpackPlugin({
            filename: `${fileName}.html`,
            template: './template.html',
            inject: true,
            chunks: [`${fileName}`, 'vendor'],
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                useShortDoctype: true,
                trimCustomFragments: true,
                removeTagWhitespace: true,
                removeStyleLinkTypeAttributes: true,
                removeScriptTypeAttributes: true,
                removeRedundantAttributes: true
            }
   });

使用HtmlWebpackPlugin

WebPack怎么tree-shake?

使用 ES2015 模块语法(即 import 和 export)。 确保没有 compiler 将 ES2015 模块语法转换为CommonJS 模块(这也是流行的 Babel preset 中 @babel/preset-env 的默认行为 – 更多详细信息请查看 文档)。 在项目 package.json 文件中,添加一个 “sideEffects” 属性。 通过将 mode 选项设置为production,启用 minification(代码压缩) 和 tree shaking。

WebPack怎么设置模块热更新?

devServer: {
        contentBase: './dist',
        compress: true,
        hot: true
    },

使用webpack-dev-middlemare webpack-hot-middlemare
server端

const express = require('express');
const webpack = require('webpack');

const app = express();

const webpackConfig = require('./webpack.config');
const compiler = webpack(webpackConfig);

app.use(require("webpack-dev-middleware")(compiler, {
    noInfo: true,
    publicPath: webpackConfig.output.publicPath
}));

app.use(require("webpack-hot-middleware")(compiler));

app.listen(3000, () => {
    console.log(3000);
});

webpack entry配置

const hotMiddlewareScript = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true';

{
    index: ['hotMiddlewareScript',  './index.js']
}


Talk is cheap. Show me the code

安装Webpack环境

mkdir learn-webpack && cd learn-webpack
npm init -y
npm install webpack webpack-cli --save-dev
touch webpack.config.js

webpack.config.js :


const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const glob = require('glob');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

const getEntries = () => {
    return glob
        .sync('src/**/*.js')
        .map(url => `./${url}`);
};

const getEntryNames = () => {
    const PRE_STR = './src/';
    const entries = {};

getEntries()
    .forEach(url => {
        const removeExtUrl = url.replace(/.js$/ig, '');
        const fileParamsWithPath = removeExtUrl.slice(PRE_STR.length).split('/');
        entries[fileParamsWithPath.join('-')] = url.replace(/.js$/, '');
    });

return entries;
};

console.log(getEntryNames());

const getWebpackHtmls = () => {
    const PRE_STR = './src/';

return getEntries()
    .map(url => {
        const removeExtUrl = url.replace(/.js$/ig, '');
        const fileParamsWithPath = removeExtUrl.slice(PRE_STR.length).split('/');
        const fileName = fileParamsWithPath.join('-');

        return new HtmlWebpackPlugin({
            filename: `${fileName}.html`,
            template: './template.html',
            inject: true,
            chunks: [`${fileName}`, 'vendor'],
            minify: {
                collapseWhitespace: true,
                removeComments: true,
                useShortDoctype: true,
                trimCustomFragments: true,
                removeTagWhitespace: true,
                removeStyleLinkTypeAttributes: true,
                removeScriptTypeAttributes: true,
                removeRedundantAttributes: true
            }
        });
    });
};

module.exports = {
    entry: getEntryNames(),
    output: {
        filename: 'static/[name].js',
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        chunkFilename: 'static/vendor.js'
    },
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
        splitChunks: {
            name: 'vendor',
            chunks: 'all',
            minChunks: 1
        }
    },
mode: 'production',
module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader,
                    options: {
                        // you can specify a publicPath here
                        // by default it uses publicPath in webpackOptions.output
                        hmr: process.env.NODE_ENV === 'development',
                    },
                },
                'css-loader'
            ]
        },
        {
            test: /\.(png|jpg|gif|svg)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'images',
                    }
                }
            ]
        },
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'fonts'
                    }
                }
            ]

        },
        {
            test: /.html$/,
            loader: [
                'html-loader'
            ]
        }
    ]
},
plugins: [
    new CleanWebpackPlugin({
        dry: false,
        dangerouslyAllowCleanPatternsOutsideProject: true
    }),
    ...getWebpackHtmls(),
    new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
        filename: 'style/[name].css',
        chunkFilename: 'style/[id].css',
    }),
    new webpack.ProvidePlugin({
        join: ['lodash', 'join']
    })
],
resolve: {
    alias: {
        '@': path.resolve('./src')
    },
    extensions: ['.js', '.jsx', '.css', '.less', '.json', 'scss', '.vue']
}
};
    原文作者:十月安徒生
    原文地址: https://segmentfault.com/a/1190000019713145
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞