密陀僧博客 记录生活日常,技术随笔

webpack+bootstrap+jquery+scss构建多界面项目

本文主要是介绍零构建了一个webpack4.x多页面应用程序。

1、项目初始化

建立相关的文件目录

 

  1. -src

  2. --js

  3. --page

  4. --public

  1. ---image

  1. --scss

通过运行以下命令初始化 package.json :

npm init -y

安装 bootstrap和jquery

npm install bootstrap jquery

并引入 webpack 4和webpack-cli 

 

  1. npm i webpack --save-dev

  2. npm i webpack-cli --save-dev 

 

打开 package.json 并填充 script 部分,如下所示:

 

  1. "scripts": {

  2. "dev": "webpack --mode development",

  3. "build": "webpack --mode production"

  1. }

2、安装配置文件使用 babel-loader

现代 Javascript 主要是用 ES6 编写的。但并非每个浏览器都知道如何处理 ES6 。 babel-loader 是一个 webpack 的 loader(加载器),用于将 ES6 及以上版本转译至 ES5 

npm i babel-core babel-loader babel-preset-env --save-dev

通过在项目文件夹中创建名为 .babelrc 的新文件来配置 Babel :

 

  1. {

  1. "presets": [

  2. "env"

  1. ]

  2. }

新建webpack.config.js进行配置babel-loader

 

  1. module.exports = {

  2. module: {

  1. rules: [

  2. {

  3. test:      /\.js$/,

  4. exclude:      /node_modules/,

  5. use:      {

  6. loader: "babel-loader"

  7. }

  8. }

  9. ]

  10. }

  11. };

构建src/index.js进行babel的测试,index.js的代码如下

 

  1. (() => {

  1. // let:      块级作用域

  1. for (let i = 0; i < 3; i++) {

  1. console.log(i) // 0 1 2

  1. }

  1. console.log(i) // Uncaught ReferenceError: i is not      defined

  1. })()

  2. (()      => {

  1. //      const: 常量 块级作用域

  1. const t2 = { a: 1}

  1. t2.a = 3

  1. console.log(t2.a) // 3    **引用类型 存放的是地址

  1. const t1 = 1

  1. t1 = 2

  1. console.log(t1) // Uncaught TypeError: Assignment to      constant variable.

  1. })()

运行npm run build命令,你会发现报以下的错,解决方法参考https://segmentfault.com/a/1190000016458913

 

  1. Error: Cannot find module '@babel/core'

  1. babel-loader@8 requires Babel 7.x (the package '@babel/core'). If      you'd like to use Babel 6.x ('babel-core'), you should install      'babel-loader@7'.

  2. at Function.Module._resolveFilename (module.js:547:15)

  3. at Function.Module._load (module.js:474:25)

  4. at Module.require (module.js:596:17)

  5. at require (internal/module.js:11:18)

  6. ....

 

3、构建处理HTML webpack 插件

webpack需要组件来处理HTML:html-webpack-plugin 和 html-loader。

npm i html-webpack-plugin html-loader --save-dev

./src/page/index.html 中创建一个 HTML 文件:

 

  1. <!DOCTYPE html>

  1. <html lang="en">

  2. <head>

  3. <meta charset="utf-8">

  4. <title>webpack</title>

  5. </head>

  6. <body>

  7. <div>

  8. aaaa

  9. </div>

  10. </body>

  11. </html>

在webpack.conf.js配置相关的loader和plugn

 

  1. const HtmlWebPackPlugin = require("html-webpack-plugin");

  2. module.exports = {

  3. module: {

  1. rules: [

  2. {

  3. test:      /\.html$/,

  4. use:      [

  5. {

  6. loader: "html-loader",

  7. options: { minimize: true }

  8. }

  9. ]

  10. }

  11. ]

  12. },

  13. plugins:      [

  1. new HtmlWebPackPlugin({

  1. template: "./src/page/index.html",

  2. filename: "./index.html"

  3. })

  4. ]

  5. };

运行 npm run build进行测试,运行成功会在dist下面生成index.html文件表示成功

4、配置入口文件集合和输出文件集合

由于要配置的是多入口文件,所有在page下面建立index.html和a.html

新建一个config.js,用来配置相关的配置,在config下建立页面集合并导出

 

  1. const HTMLDirs = ['index', 'a'];

  2. module.exports = {

  1. HTMLDirs,

  2. };

在webpack.config.js中生成页面集合,并用html-webpack-plugin对各个几面处理

 

  1. const path = require("path");

  2. const HtmlWebPackPlugin = require("html-webpack-plugin");

  3. const config = require("./config/config");

  4. let Entries = {};

  1. // 通过      html-webpack-plugin 生成的 HTML 集合

  1. let HTMLPlugins = [];

  1. //      生成多页面的集合

  1. config.HTMLDirs.forEach(page => {

  1. const htmlPlugin = new HtmlWebPackPlugin({

  1. filename: `${page}.html`,

  2. template:      path.resolve(__dirname, `./src/page/${page}.html`)

  1. });

  2. HTMLPlugins.push(htmlPlugin);

  3. Entries[page] = path.resolve(__dirname, `./src/js/${page}.js`);

  4. });

  1. module.exports = {

  1. entry: Entries,

  2. output: {

  3. filename: "js/[name].js",

  4. path:      path.resolve(__dirname, "dist"),

  5. publicPath: "/"

  1. },

  1. plugins: [...HTMLPlugins]

  1. };

5、构建处理SCSS的 插件

安装相关的loader插件npm i style-loader sass-loader node-sass css-loader

 

  1. module.exports = {

  2. module: {

  1. rules: [

  2. {

  3. test:      /\.scss$/,

  4. use:      [

  1. "style-loader",

  2. "css-loader",

  3. "sass-loader"

  1. ]

  2. }

  3. ]

  4. }

  5. };

6、配置url-loader和file-loader

url-loader和file-loader的区别其中一个就是引用路径的问题。拿 background 样式用 url 引入背景图来说,我们都知道,webpack 最终会将各个模块打包成一个文件,因此我们样式中的 url 路径是相对入口 html 页面的,而不是相对于原始 css 文件所在的路径的。这就会导致图片引入失败。这个问题是用 file-loader 解决的,file-loader 可以解析项目中的 url 引入(不仅限于 css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。

    另外,如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的的时候可以用使用file-loader进行copy。

npm i html-webpack-plugin url-loader file-loader --save-dev

配置url-loader和file-loader

 

  1. {

  1. test: /\.(gif|png|jpe?g|svg)$/i,

  1. use: [

  2. {

  3. loader: "url-loader",

  4. options:      {

  5. limit: 8192,

  6. name: "[name].[ext]",

  7. fallback: "file-loader", //超过了限制大小调用回调函数

  8. outputPath: "public/images" //图片存储的地址

  9. }

  10. }

  11. ]

  12. },

7、配置webpack-dev-server

webpack-dev-server为您提供了一个简单的Web服务器和使用实时重新加载的能力

 

  1. devServer: {

  1. contentBase: path.join(__dirname, '../src'),

  1. },

在package.json中的script添加以下命令,就会实时监听,默认端口是8080

"start": "webpack-dev-server --open",

配置到这里基本配置基本完成,接下来是对配置文件的优化和添加相关的插件等,对项目代码进行优化。

8、通过命令行识别当前是开发模式还是生产模式

安装cross-env

cross-env能跨平台地设置及使用环境变量,大多数情况下,在windows平台下使用类似于: NODE_ENV=production的命令行指令会卡住,windows平台与POSIX在使用命令行时有许多区别(例如在POSIX,使用$ENV_VAR,在windows,使用%ENV_VAR%。。。)cross-env让这一切变得简单,不同平台使用唯一指令,无需担心跨平台问题

修改packgae.json下面的script命令

 "dev": "cross-env NODE_ENV=dev webpack-dev-server --open --config webpack.config.js",

const IS_DEV = process.env.NODE_ENV === "dev"; //获取cmd命令

9、根据开发模式对输出文件和生成多页面集合进行修改

 

  1. config.HTMLDirs.forEach(page => {

  1. const htmlPlugin = new HtmlWebPackPlugin({

  1. filename: `${page}.html`,

  2. template:      path.resolve(__dirname, `./src/page/${page}.html`),

  3. chunks: [page, "commons"], //引入的模块,entry中设置多个js时,在这里引入指定的js,如果不设置则全部引入

  1. favicon:      path.resolve(__dirname, "./src/public/icon.ico"), //在网页窗口栏上加上图标

  2. minify:      !IS_DEV && {

  1. collapseWhitespace: true, //清楚空格、换行符

  1. preserveLineBreaks: true, //保留换行符

  2. removeComments: true //清理html中的注释

  3. }

  4. });

  5. HTMLPlugins.push(htmlPlugin);

  6. Entries[page] = path.resolve(__dirname, `./src/js/${page}.js`);

  7. });

 

  1. output: {

  1. filename: IS_DEV ? "js/[name].[hash:8].js" : "js/[name].[chunkhash:8].js",

  1. path: path.resolve(__dirname, "dist"),

  2. publicPath: "/"

  3. },

contenthash、hash、chunkhash的区别

hash是跟整个项目的构建有关,只要项目里面的文件有变化,hash都会更改,并且全部项目的hash值都会一样,所以每一次构建的项目都会发生改变,不利于缓存

chunkhash是根据不同的入口文件进行依赖文件的解析、构建对应的chunk,生成对应的hash值。我们在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,

接着我们采用chunkhash的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。

contenthash加入index.css被index.js引用了,那index.js和index.css的哈希值是一样的,假如index.js被修改了

index.css的hash也会修改,所以这个时候就要用到我们可以使用extra-text-webpack-plugin里的contenthash值,保证即使css文件所处的模块里就算其他文件内容改变,只要css文件内容不变,那么不会重复构建。

10、安装配置mini-css-extract-plugin插件

此插件将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持CSS和SourceMaps的按需加载。

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

对sass的loader进行修改

 

  1. {

  1. test: /\.scss$/,

  1. use: [

  2. IS_DEV ? "style-loader" : MiniCssExtractPlugin.loader, //如果是开发模式使用内嵌样式

  1. "css-loader",

  2. "sass-loader"

  1. ]

  2. },

 

 

  1. new      MiniCssExtractPlugin({

  1. filename: !IS_DEV ? "css/[name].[contenthash:8].css" : "[name].css",

  1. chunkFilename: !IS_DEV      ? "css/[name].[contenthash:8].css" : "[name].css",

  2. allChunks:      true

  3. }),

11、安装配置clean-webpack-plugin

此插件将删除webpack output.path目录中的所有文件,以及每次成功重建后所有未使用的webpack资产,避免dist文件过去混乱。

npm install clean-webpack-plugin --save-d

 new CleanWebpackPlugin(), //在构建之前清理dist文件

12、配置optimization

配置optimization可以进行手动配置和覆盖的所有优化,你可以根据不同的模式进行相关的配置对项目进行优化

optimization.minimizer

允许您通过提供不同的一个或多个自定义TerserPlugin实例来覆盖默认最小化

terser-webpack-plugin:这个插件使用terser来缩小你的JavaScript。

optimize-css-assets-webpack-plugin: 一个Webpack插件,用于优化\最小化CSS资产。解决了extract-text-webpack-plugin的重复问题,由于extract-text-webpack-plugin仅捆绑(合并)文本块,如果它用于捆绑CSS,则捆绑包可能具有重复的条目(块可以是重复的,但是当合并时,可以创建重复的CSS)。

 

  1. if (!IS_DEV) {

  2. const TerserPlugin = require("terser-webpack-plugin");

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

  1. webpackConfig.optimization.minimizer.push(

  1. new TerserPlugin({

  1. parallel: true,

  2. cache: true,

  3. extractComments: true

  1. }),

  1. new OptimizeCSSAssetsPlugin({})

  1. );

  2. }

optimization.runtimeChunk

runtime 指的是 webpack 的运行环境(具体作用就是模块解析, 加载) 和 模块信息清单,模块信息清单在每次有模块变更(hash 变更)时都会变更, 所以我们想把这部分代码单独打包出来, 配合后端缓存策略, 这样就不会因为某个模块的变更导致包含模块信息的模块(通常会被包含在最后一个 bundle 中)缓存失效. optimization.runtimeChunk 就是告诉 webpack 是否要把这部分单独打包出来.

optimization.splitChunks

最初,块(以及在其中导入的模块)通过内部webpack图中的父子关系进行连接。CommonsChunkPlugin用于避免跨越它们的重复依赖,但是无法进一步优化。从webpack v4开始,它CommonsChunkPlugin被删除了,optimization.splitChunks代替。相关查看https://webpack.js.org/plugins/split-chunks-plugin/

 

  1. splitChunks: {

  1. chunks: "async",

  1. minSize: 30000,

  2. minChunks: 1,

  3. maxAsyncRequests: 5,

  4. maxInitialRequests: 3,

  5. automaticNameDelimiter: "~",

  6. name:      true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔开,如vendor~

  7. cacheGroups:      {

  8. vendors:      {

  9. test:      /[\\/]node_modules[\\/]/,

  10. priority: -10,

  11. name: "vendors/vendors",

  12. reuseExistingChunk:      true,

  13. chunks: "async"

  14. }

  15. }

13、配置webpack.ProvidePlugin、copy-webpack-plugin、preload-webpack-plugin、css-url-relative-plugin等插件

preload-webpack-plugin:

一个Webpack插件,用于自动连接异步(和其他类型)的JavaScript块<link rel='preload'>。这有助于延迟加载。注意:这是html - webpack - plugin的扩展插件 - 这是一个简化HTML文件创建的插件,可以为您的webpack包提供服务。

webpack.ProvidePlugin

webpack配置ProvidePlugin后,在使用时将不再需要import和require进行引入,直接使用即可。

copy-webpack-plugin

将单个文件或整个目录复制到构建目录,常用来拷贝静态文件、图片等

css-url-relative-plugin

/Webpack插件将css url(...)转换为相对路径(仅支持webpack 4)。将css中的错误路劲转换为正确的路径

npm install copy-webpack-plugin preload-webpack-plugin css-url-relative-plugin --save-d

 

  1. new webpack.ProvidePlugin({

  1. $: "jquery",

  2. jQuery: "jquery"

  3. }), //自动加载模块,当在项目中遇见$、jQuery、会自动加载JQUERY模块

  1. new CopyWebpackPlugin([

  1. //将单个文件或整个目录复制到构建目录。

  1. {

  2. from: "./src/public",

  3. to: "public"

  4. }

  5. ]),

  1. new PreloadWebpackPlugin({

  2. include: "initial"

  1. }),

  1. new CssUrlRelativePlugin()


https://blog.csdn.net/weixin_42298964/article/details/88552800

作者:密陀僧 分类:技术笔记 浏览:219 评论:3
留言列表
斑马会员邀请码
斑马会员邀请码 测试了一些 有效果  回复
PDM系统
PDM系统 能这么坚持更新的还是非常的厉害的  回复
PLM系统
PLM系统 这个是非常的实用的  回复
发表评论
来宾的头像