webpack的基本使用技巧和项目优化

4736463-b5e524d0d3521b7a.jpg

webpack处理html

html-webpack-plugin这个plugin曝光率很高,他主要有两个作用

  • 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题
  • 帮助你自动生成 HTML 文件到build文件夹,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口。
    简单的来说,运行npm start之后你会神奇的看到在你的 build 文件夹会生成一个 index.html 文件和一个 bundle.js 文件,而且 index.html 文件中自动引用 webpack 生成的 bundle.js 文件。所有的这些都是 html-webpack-plugin 的功劳。

Webpack 插件使用三步曲:安装>引入>配置
npm 安装

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

yarn 安装

yarn add html-webpack-plugin --dev

引入:

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

配置:

new HtmlWebpackPlugin({
          title: 'test page', //html标题
            filename: 'index.html', //打包后的html文件名,默认index.html
            template: './index.html', // html的源文件
            inject: true, //默认true,意为script标签位于html文件的 body 底部
            cache: true, //默认true,表示内容变化的时候生成一个新的文件
            chunks: ['index'], //表示编译时用到的入口文件
            date: new Date(),
            // excludeChunks: ['index']//表示编译时排除的入口文件
        }),

如果需要复制多个页面到成产环境的话,多引入几次。
详细配置和使用方法见:webpack4 之html-webpack-plugin

webpack处理css

1最基本的CSS处理

Webpack最基本的css处理:css-loader + style-loader。其中css-loader用于处理css文件中的@import和url(...),而style-loader用于将css-loader的输出生成js中的函数调用将css动态添加到html文件中。
安装css-loader和style-loader:

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

然后配置webpack.config.js,使webpack可以将css文件当做module对待(即可以进行import操作)以及使用css-loader和style-loader对css文件进行处理。

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

css-loader 和style-loader两者使用的时候是一起使用的缺一不可并且有先后顺序的 要先使用 css-loader 转码,然后再使用 style-loader插入到文件中去安装使用。

2.单页面应用,把JS里面的CSS单独打包

style-loader将css以style标签的形式动态添加到html文件中,有时(特别是在生产环境下)我们希望将所有的css抽离为独立的css文件,此时可以借助

  • mini-css-extract-plugin
    将CSS提取为独立的文件的插件,对每个包含css的js文件都会创建一个CSS文件,然后再link进页面。支持按需加载css和sourceMap

(1).安装mini-css-extract-plugin:

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

(2).webpack.config.js 配置

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production';
module: {
    rules: [
        {
            test: /\.css$/,
            use : [
                MiniCssExtractPlugin.loader,
                { loader: "css-loader" }
            ]
        },
        {
            test: /\.less$/,
            use : [
                MiniCssExtractPlugin.loader,
                { loader: "css-loader" },
                { loader: "less-loader" }
            ]
        }
    ]
},
plugins: [
    new MiniCssExtractPlugin({
      // 这里的配置和webpackOptions.output中的配置相似
      // 即可以通过在名字前加路径,来决定打包后的文件存在的路径
      filename: devMode ? 'css/[name].css' : 'css/[name].[hash].css',
      chunkFilename: devMode ? 'css/[id].css' : 'css/[id].[hash].css',
    })
  ]
image.png
3. webpack如何打包多个CSS文件到一个css文件中

如何用webpack将css合并打包成一个单独的css,或者将css中同样的模块独立出来呢?extract-text-webpack-plugin可以将所有 required 的 *.css 模块抽取到一个单独的 CSS 文件。 所以你的样式将不会内联到 JS bundle,而是在一个单独的 CSS 文件。如果你的样式文件很大,这样会提速,因为 CSS bundle 和 JS bundle 是平行加载的。
(1).这个插件的安装方法:

npm install extract-text-webpack-plugin --save-dev

(2).webpack.config.js 配置

const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin");
module: {
   rules: [
        {
            test: /\.css$/,
            use : ExtractTextWebpackPlugin.extract({
                use: [
                    { loader: "css-loader" }
                ]
            })
        },
        {
            test: /\.less$/,
            use : ExtractTextWebpackPlugin.extract({
                use: [
                    { loader: "css-loader" },
                    { loader: "less-loader" }
                ]
            })
        }
    ]
},
plugins: [
   new ExtractTextWebpackPlugin({
        filename: "css/common.css"
    }),
 ]

详细配置可参考:extract-text-webpack-plugin

webpack处理图片

1.最基本的打包图片

图片打包关键要用到file-loader或url-loader
file-loader和url-loader模块是webpack打包中用到的一个loader。
它实现的功能很简单:

-将要加载的文件复制到指定目录
-将请求文件的url从相对于原始文件修改为相对于入口html页面

(1).安装相应的loader

//安装file-loader
npm install --save-dev file-loader
//或者安装url-loader
npm install --save-dev file-loader

其中url-loader与file-loader功能基本一致,只不过url-loader能将小于某个大小的图片进行base64格式的转化处理。
(2).在webpack.config.js中的rules数组中添加相关配置

//使用file-loader的相关配置
 {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.(png|jpg|jpeg|jsp|gif)/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        name: '[name]_[hash].[ext]', //保持打包后的图片名字和原来一样
                        outputPath: 'images/'

                    }
                }]
            }

file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。

file-loader的详细配置请参考file-loader

除了使用file-loader对图片进行打包处理外,我们同样也可以使用url-loader代替,使用url-loader我们还可以对小于某个大小的图片进行base64格式的转化处理。

{
                test: /\.(png|jpg|jpeg|jsp|gif)/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        limit: 40960,
                        name: '[name].[ext]', //保持打包后的图片名字和原来一样
                        outputPath: 'images/'
                    }
                }]
            }

这里limit属性的作用就是将小于40960B(40K)大小的图片转成base64格式,而大于这个大小的图片将会以file-loader的方式进行打包处理,例如图片小于40k的时候:


1564048064(1).jpg

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

url-loader和file-loader是什么关系呢?简答地说,url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。通过上面的介绍,我们可以看到,url-loader工作分两种情况:1.文件大小小于limit参数,url-loader将会把文件转为DataURL;2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。

参考文章:webpack学习笔记--file-loader 和 url-loader
webpack 中进行图片处理 file-loader img-loader url-loader
Webpack轻松入门—图片打包

furl-loader的详细配置请参考url-loader

2.webpack处理雪碧图

之前使用雪碧图需要用到ps去拼接然后手动写样式。
例如页面中经常会需要一些图标。例如:


image.png

使用 webpack-spritesmith
插件之后,简化了上述麻烦的步骤。我们只需要提供指定目录下的一堆小图片.它就能帮我们做如下的事情.

-把零散的小图标生成一张大图.(多个http请求变成一个)
-测量大图的中每一个小图标的大小以及位置,帮我们生成对应的 .css 文件.(不用我们自己测量尺寸和位置以及编写.css文件)

webpack-spritesmith的使用方法如下:

(1)安装 webpack-spritesmith插件

npm install --save-dev webpack-spritesmith

(2).在 webpack.config.js 中导入此插件,并设置一些此插件的相关配置.

const WebpackSpritesmithPlugin = require('webpack-spritesmith');
// 雪碧图插件
        new WebpackSpritesmithPlugin({
            // 目标小图标
            src: {
                // 小图标路径
                cwd: path.join(__dirname, 'src/images/sprite'),
                // 匹配小图标文件后缀名
                glob: '*.png'
            },
            target: {
                // 生成雪碧图(大图)文件存放路径
                image: path.join(__dirname, 'dist/images/sprites.png'),
                // 对应的样式文件存放路径
                css: path.join(__dirname, 'dist/css/sprites.css')
            },
            // 打包的样式文件中,调用雪碧图的路径
            apiOptions: {
                cssImageRef: '../images/sprites.png'
            },
            // 雪碧图生成算法
            spritesmithOptions: {
                algorithm: 'binary-tree', // binary-tree,top-down从左到右和从上到下生成方向.
                padding: 2 // 每个小图标之间的间隙
            }
        })

打包之后生成的页面结构如下:


image.png

几张图标被拼成了一张完整的图:


image.png

webpack-spritesmith的详细使用方法可如下文章:
手把手教你webpack3(15)插件之雪碧图插件(WEBPACK-SPRITESMITH配置简述)

webpack 学习笔记之十, webpack-spritesmith 雪碧图

webpack优化实践

1.webpack实现vue路由按需加载

webpack ensure相信大家都听过。有人称它为异步加载,也有人说做代码切割,那这
个家伙到底是用来干嘛的?其实说白了,它就是把js模块给独立导出一个.js文件的,然后使用这个模块的时候,webpack会构造script dom元素,由浏览器发起异步请求这个js文件。
语法如下:

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

依赖 dependencies:这是一个字符串数组,通过这个参数,在所有的回调函数的代码被执行前,我们可以将所有需要用到的模块进行声明。

回调 callback:当所有的依赖都加载完成后,webpack会执行这个回调函数。require 对象的一个实现会作为一个参数传递给这个回调函数。因此,我们可以进一步 require() 依赖和其它模块提供下一步的执行。

chunk名称 chunkName:chunkName 是提供给这个特定的 require.ensure() 的 chunk 的名称。通俗的说就是按需加载引入的那个js的文件名。需要文件名的时候需要对wenpack的output的chunkFilename和publicPath两个属性进行配置。

(1)将组件(页面)引入
传统的与引入方式为:

import List from '@/components/List'

这里需要修改为:

const List = r => require.ensure([], () => r(require('@/components/List')), 'List')

路由还按以前的方式写:

export default new Router({
  routes: [{
    path: '/',
    name: 'index',
    component: Index
  },
  {
    path: '/list',
    name: 'List',
    component: List
  }
  ]
})

详细的使用请参考文章:
三种方式分割VueJS及Webpack代码
vue按需加载组件-webpack require.ensure

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容