Webpack生成企业站静态页面 - 项目搭建_webpack打包一个静态网站-程序员宅基地

技术标签: 前端自动化构建  webpack  前端  javascript  

        现在Web前端流行的三大框架有Angular、React、Vue,很多项目经过这几年的洗礼,已经都 转型使用这三大框架进行开发,那为什么还要写纯静态页面呢?比如Vue中除了SPA单页面开发,也可以使用nuxt.js实现SSR服务端渲染,满足SEO优化。但是对于那些还是在维护老项目,使用MVC、MVP进行开发,或者觉得使用nuxtjs成本较高小型项目,从历史原因和项目实际情况考虑,会退而求其次,让前端快速完成页面框架和样式,交付后端进行数据渲染。

        虽然现在市面上开发静态页面需求量不大,作为个学习和了解,还是决定写下使用webpack如果快速完成静态页面搭建,并能像三大框架一样能实现组件化开发,并使用less/sass/styuls完成样式的预编译,提升静态页面开发效率。

一、环境搭建

1.1 创建项目

        在您的电脑上创建一个项目目录,这里命名为“island",如下图:

1.2 初始化项目

        打开cmd或者IDE编辑工具,打开命令控制台操作界面,初始化生成package.json文件,输入命令”npm init“,如下图:

        命令执行完毕后,目录中就已生成了package.json,如下较:

1.3 安装webpack

        操作命令如下:

npm i -D webpack webpack-cli

        待命令执行完毕后,项目目录中则会生成node_modules,此时webpack已安装成功,如下图:

二、webpack配置文件

2.1 创建配置文件

        在island目录下面创建webpack.config.js文件,以及源文件目录src,先在src目录下创建一个index.js文件作测试,如下l图:

        代码如下:

const { resolve } = require('path');

module.exports = {
    entry: [resolve(__dirname, './src/index.js')],
    mode: 'production'
}

        此时webpack已经可以正常运行了,在命令行中输入webpack即可,如下图:

        此时island目录中则会多出一个dist目录,在不配置情况下,默认输出目录名称为“dist”。由于output还未配置,webpack默认输出入口文件为main.js,如下图:

2.2  output配置

        output 位于对象顶级键(key),包括了一组选项,指示 webpack 如何去输出、以及在哪里输出你的「bundle、asset 和其他你所打包或使用 webpack 载入的任何内容」。

        将output对js文件输出结果进行修改,代码如下:

const { resolve } = require('path');

module.exports = {
    entry: [resolve(__dirname, './src/index.js')],
    output: {
        filename: 'app.bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    mode: 'production'
}

        此时运行结果生成入口的js则从main.js变成app.bundle.js,如下图:

2.3 js资源输出

        如下图,当我们写静态页面时,全有首页、列表页、详情页、联系我们、预约等页面,每个页面有公共资源,也有独有资源,所以这时就需要进行多谁的输出了。

        

        首衔根据上图,把所有html页面和对应页面的js创建好,如下图:

        然后在webpack.config.js中,配置好多入口文件,即可生成对应js文件了(注意:因为现在entry中是多入口文件,所以output中filename不能写死,需要改成[name]动态取对应入口文件名称),代码如下:

const { resolve } = require('path');

module.exports = {
    entry: {
        index: resolve(__dirname, './src/js/index.js'),
        list: resolve(__dirname, './src/js/list.js'),
        article: resolve(__dirname, './src/js/article.js'),
        contact: resolve(__dirname, './src/js/contact.js'),
        message: resolve(__dirname, './src/js/message.js'),
    },
    output: {
        filename: '[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    mode: 'production'
}

        此时执行webpack命令,则dist会生成对应的js文件。由于chunkfilename是根据chunk发送的请示去生成的,所以现在还不是根据此格式进行命名,这块后面再讲。如下图:

2.4 提取html页面

        提取生成html文件,需要安装html-loader和html-webpack-plugin,命令如下:

npm i -D html-loader html-webpack-plugin

       html-webpack-plugin配置参数:

名称 类型 默认值 描述
title {String} Webpack App 要用于生成的HTML文档的标题
filename {String|Function} 'index.html' 要写入HTML的文件。默认为index.html。你也可以在这里指定一个子目录(例如:assets/admin.html)。[name]占位符将被条目名称替换。也可以是函数,例如(entryName) => entryName + '.html'。
template {String} `` Webpack模板的相对或绝对路径。默认情况下,它将使用src/index。如果它存在的话。详情请参阅文档
templateContent {string|Function|false} false 是否可以使用代替模板来提供内联模板
templateParameters {Boolean|Object|Function} false 允许覆盖模板中使用的参数
inject {Boolean|String} true true || 'head' || 'body' || false将所有资源注入给定模板或templateContent中。当传递'body'时,所有javascript资源将被放置在body元素的底部。'head'将把脚本放在head元素中。传入true将根据scriptLoading选项将其添加到头部/主体。通过false将禁用自动注入。-参见inject:false示例
publicPath {String|'auto'} 'auto' 用于脚本和链接标记的publicPath
scriptLoading {'blocking'|'defer'|'module'|'systemjs-module'} 'defer' 现代浏览器支持非阻塞javascript加载('defer')以提高页面启动性能。设置为'module'添加属性type="module"。这也意味着“defer”,因为模块是自动延迟的。
favicon {String} `` 将给定的图标路径添加到输出HTML中
meta {Object} {} 允许注入元标签。例如meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}
base {Object|String|false} false 注入一个基本标签。例如:“https://example.com/path/page.html
minify {Boolean|Object} true if mode is 'production', otherwise false 控制是否以及以何种方式减少输出。
hash {Boolean} false 如果为true,则在所有包含的脚本和CSS文件中附加一个唯一的webpack编译哈希值(即main.js?hash=compilation_hash)。这对缓存很有用
cache {Boolean} true 只有在文件被更改时才发出该文件
showErrors {Boolean} true 错误详细信息将写入HTML页面
chunks {?} ? 允许你只添加一些块(例如只添加单元测试块)
chunksSortMode {String|Function} auto 允许控制块在包含到HTML之前应该如何排序。允许的值为'none' | 'auto' | 'manual' | {Function}
excludeChunks {Array.<string>} `` 允许你跳过一些块(例如不添加单元测试块)
xhtml {Boolean} false 如果为真,则将链接标记呈现为自关闭(符合XHTML)

        首先我们使用html-webpack-plugin来提取html文件,在webpack.config.js中引用,代码如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        index: resolve(__dirname, './src/js/index.js'),
        list: resolve(__dirname, './src/js/list.js'),
        article: resolve(__dirname, './src/js/article.js'),
        contact: resolve(__dirname, './src/js/contact.js'),
        message: resolve(__dirname, './src/js/message.js'),
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    plugins: [
        new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/index.html`),
            filename: 'index.html',
            chunks: ['index'],
            minify: false
        }),
        new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/list.html`),
            filename: 'list.html',
            chunks: ['list'],        // chunk发送请求生成对应js文件,并引入html中
            minify: false
        })
    ],
    mode: 'production'
}

        如上,先生成首页和列表页的html页面,执行webpack,结果如下图:

        此时在dist目录中已生成了index.html和list.html页面,并且打开index.html页面发现index.bundle.js也自动添加到html页面中了。

2.5 html中图片资源处理

        首先,在src目录下创建images目录用于存储图片资源,并且在index.html页面中添加几张图片引入代码,如下图:

        执行webpack命令后,结果如下图:

        从上图可以看出生成的index.html页面中,资源路径还是和源文件index.html中路径一样,未根据dist目录重构,而且dist目录中也没生成对应images目录及图上资源。从而得出结论html-webpack-plugin并未处理html内容中的图片资源,这里我们将使用html-loader来实现图片资源的提取。

        html-loader配置参数:

名称 类型 默认值 描述
sources {Boolean|Object} true 启用/禁用 sources 处理
preprocessor {Function}      undefined 允许在处理前对内容进行预处理
minimize {Boolean|Object} 在生产模式下为 true,其他情况为 false 通知 html-loader 压缩 HTML
esModule {Boolean}  true 启用/禁用 ES modules 语法

        代码如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        index: resolve(__dirname, './src/js/index.js'),
        list: resolve(__dirname, './src/js/list.js'),
        article: resolve(__dirname, './src/js/article.js'),
        contact: resolve(__dirname, './src/js/contact.js'),
        message: resolve(__dirname, './src/js/message.js'),
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/index.html`),
            filename: 'index.html',
            chunks: ['index'],
            minify: false
        }),
        new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/list.html`),
            filename: 'list.html',
            chunks: ['list'],
            minify: false
        })
    ],
    mode: 'production'
}

        此时再运行webpack命令,图片资源就可以构建到dist目录指定位置了,并且index.html中图片资源也一起更新成dist目录中新路径,如下图:

2.6 优化配置文件

         由于后期项目中页面会不断增加,webpack.config.js中同需不断在entry和plugins中添加新内容,久而久之代码会显示的很臃肿,这里将页面部分独立出来,在island目录中新建static.config.js文件,如下图:

        static.config.js文件代码如下,后期有新增页面时,在此配置即可。

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 引用JS文件
const scripts = ["index", "list", "article", "contact", "message"];
// 需要生成的静态页面
const htmls = [
    {name: "index.html", chunks: ['index']},
    {name: "list.html", chunks: ['list']},
    {name: "article.html", chunks: ['article']},
    {name: "contact.html", chunks: ['contact']},
    {name: "message.html", chunks: ['message']}
];
/**
 * 静态页面配置
 */
module.exports = {
    // 重组js入口文件
    entrys: () => {
        let params = {};
        scripts.forEach(name => {
            params[name] = resolve(__dirname, `./src/js/${name}.js`);
        })
        return params;
    },
    // 重组静态页面文件
    staticHtmls: () =>  htmls.map(item => {
        return new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/${item.name}`),
            filename: item.name,
            chunks: item.chunks,
            minify: false
        });
    })
}

        webpack.config.js文件代码如下:

const { resolve } = require('path');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        ...staticHtmls()
    ],
    mode: 'production'
}

        优化完成后,此时再运行webpack,所有页面则全部生成,如下图:

2.7 css文件引入

        处理css样式文件,需要安装三个loader,命令如下:

npm i -D style-loader css-loader less-loader

        webpack.config.js中添加处理样式文件的loader,代码如下:

const { resolve } = require('path');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // style-loader 把 CSS 插入到 DOM 中。
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: ["style-loader", 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: ["style-loader", 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        ...staticHtmls()
    ],
    mode: 'production'
}

        在src目录下创建css目录用于存储样式文件,并创建index.less文件,在js/index.js中引入。

        index.less代码如下:

#app{
    margin: 0;
    padding: 0;
}

        js/index.js代码如下:

import '../css/index.less';

        添加后,运行webpack.config.js会发现,构建后的css内容是写在js/index.js文件中,并且index.html在浏览器中打开时,样式内容被动态注入到html页面中,如下图:

2.8 提取CSS为单独文件

        如何提出CSS为单独文件,并能像js文件一样,将引用链接自动添加到html内容中呢?这里就要用到一个新插件:mini-css-extract-plugin,通过命令进行安装,代码如下:

npm i -D mini-css-extract-plugin

        安装完成后,也是通过new实例并放在pugins。另外需要注意的是module中style-loader要替换成mini-css-extract-plugin插件的loader,这个插件将CSS提取到单独的文件中,为每个包含CSS的JS文件创建一个CSS文件,它支持按需加载CSS和SourceMaps。

        它建立在webpack v4新特性(模块类型)之上,需要webpack 4及以上版本才能工作。

        webpack.config.js 代码如下:

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // style-loader 把 CSS 插入到 DOM 中。
            // MiniCssExtractPlugin.loader 提取CSS为独立文件
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        ...staticHtmls(),
        // 提取css文件
        new MiniCssExtractPlugin({
            filename: 'css/[name]_bundle.css',      //输出文件
        })
    ],
    mode: 'production'
}

        此时运行webpack,样式文件则提取了来了,结果如下图:

2.9 alias别名

        创建 import 或 require 的别名,来确保模块引入变得更简单。例如,指定样式文件src/css 文件夹下的常用模块:

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // style-loader 把 CSS 插入到 DOM 中。
            // MiniCssExtractPlugin.loader 提取CSS为独立文件
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        ...staticHtmls(),
        // 提取css文件
        new MiniCssExtractPlugin({
            filename: 'css/[name]_bundle.css',      //输出文件
        })
    ],
    resolve: {
        alias: {
            // 样式目录路径别名
            $css: resolve(__dirname, 'src/css')
        }
    },
    mode: 'production'
}

        将index.js中引入的样式文件路径,用$css替换,代码如下:

import '../css/index.less';

替换为

import '$css/index.less';

        此时再运行webpack,结果还是一样的,样式文件正常构建成功。

2.10 本地服务(devServer)

        webpack-dev-server 能够用于快速开发应用程序,创建本地服务运行;当服务启动时,会解析指定dist目录。

        要想使用devServer,要先安装webpack-dev-server,安装命令:

npm i -D webpack-dev-server

        webpack.config.js 代码如下:

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // style-loader 把 CSS 插入到 DOM 中。
            // MiniCssExtractPlugin.loader 提取CSS为独立文件
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
        ]
    },
    plugins: [
        ...staticHtmls(),
        // 提取css文件
        new MiniCssExtractPlugin({
            filename: 'css/[name]_bundle.css',      //输出文件
        })
    ],
    resolve: {
        alias: {
            // 样式路径目录别名
            $css: resolve(__dirname, 'src/css')
        }
    },
    mode: 'production',
    devServer: {
        static: {
            // 指定服务运行目录
            directory: resolve(__dirname, 'dist')
        },
        compress: true,     //gzip压缩
        port: 3000,         //指定端口号
        open: true,         //服务启动后自动在浏览器打开
        hot: true           //开启热更
    }
}

        devServer添加完成后,在控制台输入命名npx webpack serve,等待服务开始即可。运行结果如下:

2.11 公共文件

        在项目中,会有公共的样式和js功能,所以创建common.js和common.less文件(注意common.less文件需要在common.js文件中引入),如下图:

        common.js文件代码如下:

import '$css/common.less';

        另外将common.js放入到htmlWebpackPlugin的chunks中(注意:entry入口中也要添加common,这里放在scipts数组中)。

        static.config.js 代码如下:

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 引用JS文件
const scripts = ["common", "index", "list", "article", "contact", "message"];
// 需要生成的静态页面
const htmls = [
    {name: "index.html", chunks: ['index']},
    {name: "list.html", chunks: ['list']},
    {name: "article.html", chunks: ['article']},
    {name: "contact.html", chunks: ['contact']},
    {name: "message.html", chunks: ['message']}
];
/**
 * 静态页面配置
 */
module.exports = {
    // 重组js入口文件
    entrys: () => {
        let params = {};
        scripts.forEach(name => {
            params[name] = resolve(__dirname, `./src/js/${name}.js`);
        })
        return params;
    },
    // 重组静态页面文件
    staticHtmls: () =>  htmls.map(item => {
        return new HtmlWebpackPlugin({
            inject: 'body',
            template: resolve(__dirname, `./src/${item.name}`),
            filename: item.name,
            chunks: ['common', ...item.chunks],
            minify: false
        });
    })
}

        此时运行webpack,common.js和common.css则已生成出来,并且引入到所有html内容中,如下图:

2.12 引用jquery

        由于静态页面中资源都打包到一个文件中,体积会越积越大,所以这里将jquery整体暴露给window,这就需要使用到另个loader,首先先安装jquery和expose-loader,命令如下:

// 安装jquery插件
npm i -S jquery
// 安装expose-loader
npm i -D expose-loader

        安装完成后,我们先在common.js文件中添加浏览器控制台输入,并且将jquery构建到dist/js目录中。

        webpack.config.js文件中添加jquery入口文件,如下图:

        static.config.js文件中将jquery添加到每个html谁的的chunks中,如下图

        common.js文件代码如下:

import '$css/common.less';

console.log('jquery', jQuery);

        此是运行npx webpack serve,在浏览器打开控制台查看,如下图:

        结果显示jquery不存在,这是因为我们安装的jquery还没有暴露给window对象,现在把expose-loader添加到webpack.config.js中再看看效果,代码如下:

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { entrys, staticHtmls } = require('./static.config');

module.exports = {
    entry: {
        jquery: ['jquery'],
        ...entrys()
    },
    output: {
        filename: 'js/[name].bundle.js',      // 对入口名称进行命名,
        clean: true                     // 在生成文件之前清空 output 目录
    },
    module: {
        rules: [
            // style-loader 把 CSS 插入到 DOM 中。
            // MiniCssExtractPlugin.loader 提取CSS为独立文件
            // css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader']
            },
            // webpack 将 Less 编译为 CSS 的 loader。
            {
                test: /\.less$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
            },
            // 匹配图片资源,指定构建后存储位置和命名
            {
                test: /\.(png|jpg|jpeg|svg|gif)$/i,
                type: 'asset/resource',
                generator: {
                    filename: 'images/[name].[ext]'
                }
            }, 
            // 匹配html页面,并提取内部资源文件
            {
                test: /\.html$/i,
                loader: "html-loader",
                exclude: /node_modules/,
                options: {
                    minimize: false,        // 不压缩html内容
                }
            },
            // 将jquery暴露给全局对象(self、window 和 global)
            {
                test: require.resolve('jquery'),
                loader: "expose-loader",
                options: {
                    exposes: ["$", "jQuery"]
                }
            }
        ]
    },
    plugins: [
        ...staticHtmls(),
        // 提取css文件
        new MiniCssExtractPlugin({
            filename: 'css/[name]_bundle.css',      //输出文件
        })
    ],
    resolve: {
        alias: {
            // 样式路径目录别名
            $css: resolve(__dirname, 'src/css')
        }
    },
    mode: 'production',
    devServer: {
        static: {
            // 指定服务运行目录
            directory: resolve(__dirname, 'dist')
        },
        compress: true,     //gzip压缩
        port: 3000,         //指定端口号
        open: true,         //服务启动后自动在浏览器打开
        hot: true           //开启热更
    }
}

        expose-loader添加完成后,再运行npx webpack serve,此时jquery在浏览器中则可以全局调用了,如下图:

三、package.json

        最后整理一下项目中所需要的loader、plugin,以及其对应的版本和功能描述。

名称 版本 描述
webpack ^5.91.0 webpack
webpack-cli ^5.1.4 webpack脚手架
webpack-dev-server ^5.0.4 构建本地开发服务
css-loader ^6.10.0 处理css文件(css-loader会像import/require()一样解释@import和url(),并解析它们。)
style-loader ^3.3.4 通过注入<style>标签向DOM添加CSS
less-loader ^12.2.0 处理 less 的 webpack loader。将 Less 编译为 CSS。
mini-css-extract-plugin ^2.8.1 将CSS提取到单独的文件中
html-loader ^5.0.0 HTML导出为字符串。当编译器需要时,提取HTML内容中资源文件。
html-webpack-plugin ^5.6.0 生成 HTML5 文件
expose-loader ^5.0.0 允许暴露一个模块(整体或者部分)给全局对象(self、window 和 global)

        本篇内容就先讲到这,如果还需其他功能做进一步完善,可以去webpack了解,地址:webpack 中文文档(@印记中文) https://docschina.org/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jiciqiang/article/details/137010572

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文