Skip to content

打包文件分类

在上一节中,我们将图片打包到了build目录下。我们通过配置,还可以将静态资源进行分类,即打包的时候生成对应目录下。

比如,我们希望css放在一个目录下,图片放在一个目录下。

图片的打包后生成在指定目录下

修改配置文件

js
// webpack-dev-1\webpack.config.js
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入插件

let OptimizeCss = require('optimize-css-assets-webpack-plugin') // 引入插件 压缩css的
let UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 压缩js文件的插件


module.exports = {
    // 配置优化项
    optimization: {
        minimizer: [ // 是一个数组,还得优化js
            new UglifyJsPlugin({
                cache: true, // 是否用缓存
                parallel: true, // 是否并发压缩
                sourceMap: true,// 线上用来调试的映射文件
            }),
            new OptimizeCss(), // 开启优化css后,生产模式css文件也会被压缩,但是必须配置js压缩,如果不配置,js生产模式就不会被压缩了
        ]
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: './src/index.js', // 入口

    output: {
        filename: 'bundle.js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        }),
        // 插件的使用就没有先后顺序了,随便放就行
        // 引入抽离css样式的插件,
        new MiniCssExtractPlugin({
            filename: 'main.css', // 告诉插件,抽离出的样式文件的名字叫什么,这里叫main.css
        }),
    ],
    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            {
                test: /\.html$/, // 解析html中的img标签图片路径
                use: 'html-withimg-loader'
            },
            {
                test: /.(jpg|png|gif)$/,
                // 做一个限制,当图片小于 多少k的时候,用base64来转化
                // 如果大于这个限制,就会使用file-loader来去解析图片,将图片打包到build目录下
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1, // 单位是 B,
                        outputPath: '/img/', // 打包后的图片生成到指定目录下
                    }
                },
            },
            /* {
                test: /.(jpg|png|gif)$/, // 处理图片的loader
                use: 'file-loader'
            }, */
            {
                test: /\.js$/, // 匹配以js结尾的文件
                use: {
                    loader: 'babel-loader',
                    options: { // 用babel-loader 需要把ES6转为ES5
                        // 配置可以写在这里,还可以写在外面
                        // 在这里添加一个预设
                        presets: [ // 这是一个大插件的集合
                            '@babel/preset-env', // 这个插件就可以把ES6转ES5
                        ],
                        // 如果有一些预设的属性,需要配置一些小插件来转换还不是标准的js语法
                        plugins: [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ['@babel/plugin-proposal-class-properties', { "loose": true }],
                            "@babel/plugin-transform-runtime"
                        ]
                    }
                },
                include: path.resolve(__dirname, 'src'), // 只找src目录下的js  包括
                exclude: /node_modules/ // node_modules文件夹下的文件不用找  排除
            },

            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                ]
            },
            {
                test: /\.less$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader, // 若果想抽离多个文件,可以在new一个出来,一个抽离css一个抽离less都行
                    // 这里就用一个了
                    'css-loader', // 解析 @import语法 解析 css
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                    'less-loader' // 把less 转换为 css
                ]
            },
        ],
    }
}

重新打包,发现已经生效

image-20220114100148992

图片的引用也并没有出错。

image-20220114100201185

将样式打包到指定目录下

修改配置文件

js
// webpack-dev-1\webpack.config.js
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入插件

let OptimizeCss = require('optimize-css-assets-webpack-plugin') // 引入插件 压缩css的
let UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 压缩js文件的插件


module.exports = {
    // 配置优化项
    optimization: {
        minimizer: [ // 是一个数组,还得优化js
            new UglifyJsPlugin({
                cache: true, // 是否用缓存
                parallel: true, // 是否并发压缩
                sourceMap: true,// 线上用来调试的映射文件
            }),
            new OptimizeCss(), // 开启优化css后,生产模式css文件也会被压缩,但是必须配置js压缩,如果不配置,js生产模式就不会被压缩了
        ]
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: './src/index.js', // 入口

    output: {
        filename: 'bundle.js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        }),
        // 插件的使用就没有先后顺序了,随便放就行
        // 引入抽离css样式的插件,
        new MiniCssExtractPlugin({
            filename: '/css/main.css', // 告诉插件,抽离出的样式文件的名字叫什么,这里叫main.css
            // filename前面可以配置压缩后的文件生成目录
            // 比如 /css/main.css
        }),
    ],
    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            {
                test: /\.html$/, // 解析html中的img标签图片路径
                use: 'html-withimg-loader'
            },
            {
                test: /.(jpg|png|gif)$/,
                // 做一个限制,当图片小于 多少k的时候,用base64来转化
                // 如果大于这个限制,就会使用file-loader来去解析图片,将图片打包到build目录下
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1, // 单位是 B,
                        outputPath: '/img/', // 打包后的图片生成到指定目录下
                    }
                },
            },
            /* {
                test: /.(jpg|png|gif)$/, // 处理图片的loader
                use: 'file-loader'
            }, */
            {
                test: /\.js$/, // 匹配以js结尾的文件
                use: {
                    loader: 'babel-loader',
                    options: { // 用babel-loader 需要把ES6转为ES5
                        // 配置可以写在这里,还可以写在外面
                        // 在这里添加一个预设
                        presets: [ // 这是一个大插件的集合
                            '@babel/preset-env', // 这个插件就可以把ES6转ES5
                        ],
                        // 如果有一些预设的属性,需要配置一些小插件来转换还不是标准的js语法
                        plugins: [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ['@babel/plugin-proposal-class-properties', { "loose": true }],
                            "@babel/plugin-transform-runtime"
                        ]
                    }
                },
                include: path.resolve(__dirname, 'src'), // 只找src目录下的js  包括
                exclude: /node_modules/ // node_modules文件夹下的文件不用找  排除
            },

            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                ]
            },
            {
                test: /\.less$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader, // 若果想抽离多个文件,可以在new一个出来,一个抽离css一个抽离less都行
                    // 这里就用一个了
                    'css-loader', // 解析 @import语法 解析 css
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                    'less-loader' // 把less 转换为 css
                ]
            },
        ],
    }
}

重新打包,已经生效了。

所有的资源引用增加公共域名

在配置文件的output中添加publicPath

js
// webpack-dev-1\webpack.config.js
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入插件

let OptimizeCss = require('optimize-css-assets-webpack-plugin') // 引入插件 压缩css的
let UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 压缩js文件的插件


module.exports = {
    // 配置优化项
    optimization: {
        minimizer: [ // 是一个数组,还得优化js
            new UglifyJsPlugin({
                cache: true, // 是否用缓存
                parallel: true, // 是否并发压缩
                sourceMap: true,// 线上用来调试的映射文件
            }),
            new OptimizeCss(), // 开启优化css后,生产模式css文件也会被压缩,但是必须配置js压缩,如果不配置,js生产模式就不会被压缩了
        ]
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: './src/index.js', // 入口

    output: {
        filename: 'bundle.js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
        publicPath: 'http://bnbiye.cn', // 为所有的资源引用增加一个公共的域名前缀
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        }),
        // 插件的使用就没有先后顺序了,随便放就行
        // 引入抽离css样式的插件,
        new MiniCssExtractPlugin({
            filename: '/css/main.css', // 告诉插件,抽离出的样式文件的名字叫什么,这里叫main.css
            // filename前面可以配置压缩后的文件生成目录
            // 比如 /css/main.css
        }),
    ],
    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            {
                test: /\.html$/, // 解析html中的img标签图片路径
                use: 'html-withimg-loader'
            },
            {
                test: /.(jpg|png|gif)$/,
                // 做一个限制,当图片小于 多少k的时候,用base64来转化
                // 如果大于这个限制,就会使用file-loader来去解析图片,将图片打包到build目录下
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1, // 单位是 B,
                        outputPath: '/img/', // 打包后的图片生成到指定目录下
                    }
                },
            },
            /* {
                test: /.(jpg|png|gif)$/, // 处理图片的loader
                use: 'file-loader'
            }, */
            {
                test: /\.js$/, // 匹配以js结尾的文件
                use: {
                    loader: 'babel-loader',
                    options: { // 用babel-loader 需要把ES6转为ES5
                        // 配置可以写在这里,还可以写在外面
                        // 在这里添加一个预设
                        presets: [ // 这是一个大插件的集合
                            '@babel/preset-env', // 这个插件就可以把ES6转ES5
                        ],
                        // 如果有一些预设的属性,需要配置一些小插件来转换还不是标准的js语法
                        plugins: [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ['@babel/plugin-proposal-class-properties', { "loose": true }],
                            "@babel/plugin-transform-runtime"
                        ]
                    }
                },
                include: path.resolve(__dirname, 'src'), // 只找src目录下的js  包括
                exclude: /node_modules/ // node_modules文件夹下的文件不用找  排除
            },

            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                ]
            },
            {
                test: /\.less$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader, // 若果想抽离多个文件,可以在new一个出来,一个抽离css一个抽离less都行
                    // 这里就用一个了
                    'css-loader', // 解析 @import语法 解析 css
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                    'less-loader' // 把less 转换为 css
                ]
            },
        ],
    }
}

重新打包,已经生效

image-20220114100844020

如果不想把所有的都加,可以在单独的位置配置,比如只在css的资源增加公共域名

js
// webpack-dev-1\webpack.config.js
// webpack是node写出来的,所以使用node的语法

let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // 引入插件

let OptimizeCss = require('optimize-css-assets-webpack-plugin') // 引入插件 压缩css的
let UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 压缩js文件的插件


module.exports = {
    // 配置优化项
    optimization: {
        minimizer: [ // 是一个数组,还得优化js
            new UglifyJsPlugin({
                cache: true, // 是否用缓存
                parallel: true, // 是否并发压缩
                sourceMap: true,// 线上用来调试的映射文件
            }),
            new OptimizeCss(), // 开启优化css后,生产模式css文件也会被压缩,但是必须配置js压缩,如果不配置,js生产模式就不会被压缩了
        ]
    },

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩

    },

    mode: 'development', // 模式,默认两种模式 production 和 development

    entry: './src/index.js', // 入口

    output: {
        filename: 'bundle.js', // 打包后的文件名
        path: path.resolve(__dirname, 'build'), // 打包后的路径,必须是一个绝对路径
        // publicPath: 'http://bnbiye.cn', // 为所有的资源引用增加一个公共的域名前缀
    },


    plugins: [ // 是一个数组,放着所有的webpack插件
        // 插件是一个类,通过new的方式来引用
        new HtmlWebpackPlugin({
            template: './src/index.html', // 告诉插件,是以这个目录下的index.html为模板
            filename: 'index.html', // 告诉插件,打包后的文件叫什么名字,这里也叫index.html
            hash: true, // 引用的时候可以加一个hash戳
        }),
        // 插件的使用就没有先后顺序了,随便放就行
        // 引入抽离css样式的插件,
        new MiniCssExtractPlugin({
            filename: '/css/main.css', // 告诉插件,抽离出的样式文件的名字叫什么,这里叫main.css
            // filename前面可以配置压缩后的文件生成目录
            // 比如 /css/main.css
        }),
    ],
    module: { // 模块
        rules: [ // 规则,在这里面配置各种loader
            {
                test: /\.html$/, // 解析html中的img标签图片路径
                use: 'html-withimg-loader'
            },
            {
                test: /.(jpg|png|gif)$/,
                // 做一个限制,当图片小于 多少k的时候,用base64来转化
                // 如果大于这个限制,就会使用file-loader来去解析图片,将图片打包到build目录下
                use: {
                    loader: 'url-loader',
                    options: {
                        limit: 1, // 单位是 B,
                        outputPath: '/img/', // 打包后的图片生成到指定目录下
                        publicPath: 'http://bnbiye.cn', // 引用的图片资源都增加一个公共的域名前缀
                    }
                },
            },
            /* {
                test: /.(jpg|png|gif)$/, // 处理图片的loader
                use: 'file-loader'
            }, */
            {
                test: /\.js$/, // 匹配以js结尾的文件
                use: {
                    loader: 'babel-loader',
                    options: { // 用babel-loader 需要把ES6转为ES5
                        // 配置可以写在这里,还可以写在外面
                        // 在这里添加一个预设
                        presets: [ // 这是一个大插件的集合
                            '@babel/preset-env', // 这个插件就可以把ES6转ES5
                        ],
                        // 如果有一些预设的属性,需要配置一些小插件来转换还不是标准的js语法
                        plugins: [
                            ["@babel/plugin-proposal-decorators", { "legacy": true }],
                            ['@babel/plugin-proposal-class-properties', { "loose": true }],
                            "@babel/plugin-transform-runtime"
                        ]
                    }
                },
                include: path.resolve(__dirname, 'src'), // 只找src目录下的js  包括
                exclude: /node_modules/ // node_modules文件夹下的文件不用找  排除
            },

            // css-loader 解析css文件,@import语法的
            // style-loader 把解析后的css文件 插入到head标签中
            // loader有个特点,希望单一,一个loader干一件事
            /* 
                loader的用法
                1. 只用字符串,就是只用一个loader
                2. 多个loader,需要一个数组 [],数组里可以放字符串,或者对象,对象的话就可以配置loader的参数了
            */
            // loader的顺序,默认是从右向左执行,从下往上执行
            {
                test: /\.css$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                ]
            },
            {
                test: /\.less$/,
                use: [
                    // 这个插件上有个loader,我们不想再用style-loader把样式放在style标签里了,所以就用它的loader
                    MiniCssExtractPlugin.loader, // 若果想抽离多个文件,可以在new一个出来,一个抽离css一个抽离less都行
                    // 这里就用一个了
                    'css-loader', // 解析 @import语法 解析 css
                    // 应该在解析css之前增加前缀
                    'postcss-loader',
                    'less-loader' // 把less 转换为 css
                ]
            },
        ],
    }
}

打包看下效果,发现只有图片资源有公共域名前缀

image-20220114101118262

总结

webpack可以将静态资源文件打包到指定目录下

  1. 使用url-loader,打包图片资源时,配置 outputPath,将打包后的图片归类到统一目录下
  2. 使用 MinCssExtractPlugin时,将css文件也可以打包到指定目录下,修改filename字段,前面增加输出目录。

同时在引用静态资源文件时,还可以增加公共域名前缀

只需要配置webpack的publicPah配置,配置这个字段后,所有的外部引用都会增加公共前缀。

如果只需要单独一类的文件引用增加公共路径时,可以在相应的loader或者plugin中配置。

参考

https://www.bilibili.com/video/BV1a4411e7Bz?p=11&spm_id_from=pageDriver