Webpack常见静态资源处理-模块加载器Loaders+ExtractTextPlugin插件

webpack系列目录

基于webpack搭建纯静态页面型前端工程解决方案模板, 最终形态源码见github:

正文

Webpack将所有静态资源都认为是模块,比如JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,图片等等,从而可以对其进行统一管理。为此Webpack引入了加载器的概念,除了纯JavaScript之外,每一种资源都可以通过对应的加载器处理成模块。和大多数包管理器不一样的是,Webpack的加载器之间可以进行串联,一个加载器的输出可以成为另一个加载器的输入。比如LESS文件先通过less-load处理成css,然后再通过css-loader加载成css模块,最后由style-loader加载器对其做最后的处理,从而运行时可以通过style标签将其应用到最终的浏览器环境。

一 常用loader

安装css/sass/less loader加载器

代码如下:

webpack.config.js配置:

index.html 新增两个div

index.css 增加两个图片,同时将webpack.png(53kb) 和 small-webpack.png(9.8k)

index.js 引入css

执行webpack指令

$ webpack

查看生成的目录结构

其中并没有css文件,css被写入到了index.js中,index.js 部分截图

总结:

图片采用了url-loader加载,如果小于10kb,图片则被转化成 base64 格式的 dataUrl

css文件被打包进了js文件中

css被打包进了js文件,如果接受不了,可以强制把css从js文件中独立出来。官方文档是以插件形式实现:

二:extract-text-webpack-plugin 插件介绍

Extract text from bundle into a file.从bundle中提取出特定的text到一个文件中。使用 extract-text-webpack-plugin就可以把css从js中独立抽离出来

安装

使用(css为例)

它将从每一个用到了require("style.css")的entry chunks文件中抽离出css到单独的output文件

API

new ExtractTextPlugin([id: string],filename: string,[options])

  1. id Unique ident for this plugin instance. (For advanded usage only,by default automatic generated)
  2. filename the filename of the result file. May contain [name],[id] and [contenthash].
    1. [name] the name of the chunk
    2. [id] the number of the chunk
    3. [contenthash] a hash of the content of the extracted file
  3. options
    1. allChunks extract fromall additional chunks too (by default it extracts only from the initial chunk(s))
    2. disable disables the plugin

ExtractTextPlugin.extract([notExtractLoader],loader,[options])

根据已有的loader,创建一个提取器(loader的再封装)

  1. notExtractLoader (可选)当css没有被抽离时,加载器不应该使用(例如:当allChunks:false时,在一个additional 的chunk中)
  2. loader 数组,用来转换css资源的加载器s
  3. options
    1. publicPath 重写该加载器(loader)的 publicPath 的设置

多入口文件的extract的使用示例:

// multiple extract instances
let extractCSS = new ExtractTextPlugin('stylesheets/[name].css');
let extractLESS = new ExtractTextPlugin('stylesheets/[name].less');

module.exports = {
...
module: {
loaders: [
{test: /.scss$/i,loader: extractCSS.extract(['css','sass'])},{test: /.less$/i,loader: extractLESS.extract(['css','less'])},...
]
},plugins: [
extractCSS,extractLESS
]
};

三:改造项目-抽离css

安装插件到项目

配置webpack.config.js,加入ExtractTextPlugin和相关处理:

for (var i = 0; i < entryFiles.length; i++) {
var filePath = entryFiles[i];
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1,filePath.lastIndexOf('.'));
map[filename] = filePath;
}
return map;
}

var html_plugins = function () {
var entryHtml = glob.sync(srcDir + '/*.html')
var r = []
var entriesFiles = entries()
for (var i = 0; i < entryHtml.length; i++) {
var filePath = entryHtml[i];
var filename = filePath.substring(filePath.lastIndexOf('\/') + 1,filePath.lastIndexOf('.'));
var conf = {
template: 'html!' + filePath,filename: filename + '.html'
}
//如果和入口js文件同名
if (filename in entriesFiles) {
conf.inject = 'body'
conf.chunks = ['vendor',filename]
}
//跨页面引用,如pageA,pageB 共同引用了common-a-b.js,那么可以在这单独处理
//if(pageA|pageB.test(filename)) conf.chunks.splice(1,'common-a-b')
r.push(new HtmlWebpackPlugin(conf))
}
return r
}
var plugins = [];
var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]')
var cssLoader = extractCSS.extract(['css'])
var sassLoader = extractCSS.extract(['css','sass'])

plugins.push(extractCSS);

plugins.push(new CommonsChunkPlugin({
name: 'vendor',minChunks: Infinity
}));

module.exports = {
entry: Object.assign(entries(),{
// 用到什么公共lib(例如jquery.js),就把它加进vendor去,目的是将公用库单独提取打包
'vendor': ['jquery','avalon']
}),output: {
path: path.join(__dirname,"dist"),filename: "[name].js",chunkFilename: '[chunkhash:8].chunk.js',publicPath: "/"
},module: {
loaders: [
{
test: /.((woff2?|svg)(\?v=[0-9].[0-9].[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/,loaders: [
//小于10KB的图片会自动转成dataUrl,
'url?limit=10000&name=img/[hash:8].[name].[ext]',speed:4}}'
]
},{
test: /.((ttf|eot)(\?v=[0-9].[0-9].[0-9]))|(ttf|eot)$/,loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'
},loader: cssLoader},{test: /.scss$/,loader: sassLoader}
]
},resolve: {
extensions: ['','.js','.css','.scss','.tpl','.png','.jpg'],root: [srcDir,nodeModPath],alias: pathMap,publicPath: '/'
},plugins: plugins.concat(html_plugins())
}

其中,用ExtractTextPlugin 来抽离css

plugins.push(extractCSS);
......
//conf - module - loaders
{test: /.css$/,loader: sassLoader}

注意事项:

css中img的路径会出现问题,通过设置publicPath 解决,采用绝对路径

运行:

$ webpack

期望

  1. css单独抽离,打包成单独的css文件
  2. html自动引用css文件
  3. 小于10k的图片,转成base64 格式的 dataUrl
  4. webpack.png 会被压缩,减少文件大小

运行webpack后的项目的目录结构:

生成的 dist/index.html 自动引用了 index.css 和相关的js,由于设置了publicPath 所以相应的链接都采用了绝对路径

生成的 dist/index.css 小图片被转成了data:image形式:

结果:

  1. css单独打包到css目录
  2. html自动注入了link 标签
  3. small-webpack.png 小于10k,被打包进了index.css
  4. webpack.png 由原来的50+k 被压缩成 10- k

最后,运行 webpack-dev-server 看一下运行结果:

总结

Webpack将所有静态资源都认为是模块,而通过loader,几乎可以处理所有的静态资源,图片、css、sass之类的。并且通过一些插件如extract-text-webpack-plugin,可以将共用的css抽离出来

下篇介绍改进webpack.config.js:

  1. 区分开发环境和生产环境
  2. 集成 gulp 实现自动构建打包部署
  3. github 发布 前端自动化构建的项目模板

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)