全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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

webpack系列目录

webpack 系列 二:webpack 介绍&安装

webpack 系列 三:webpack 如何集成第三方js库

webpack 系列 四:webpack 多页面支持 & 公共组件单独打包

webpack 系列 五:webpack Loaders 模块加载器

webpack 系列 六:前端项目模板-webpack+gulp实现自动构建部署

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

正文

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加载器

复制代码 代码如下:
cnpm install file-loader css-loader style-loader sass-loader ejs-loader html-loader jsx-loader image-webpack-loader --save-dev

webpack.config.js配置:

module: {
 loaders: [
  {
   test: /\.((woff2?|svg)(\?v=[0-9]\.[0-9]\.[0-9]))|(woff2?|svg|jpe?g|png|gif|ico)$/,
   loaders: [
    // 小于10KB的图片会自动转成dataUrl
    'url?limit=10240&name=img/[hash:8].[name].[ext]',
    'image?{bypassOnDebug:true, progressive:true,optimizationLevel:3,pngquant:{quality:"65-80",speed:4}}'
   ]
  },
  {
   test: /\.((ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9]))|(ttf|eot)$/,
   loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'
  },
  {test: /\.(tpl|ejs)$/, loader: 'ejs'},
  {test: /\.css$/, loader: 'style-loader!css-loader'},
  { test: /\.scss$/, loader: 'style!css!sass'}
 ]
},

index.html 新增两个div

<div class="small-webpack"></div>
<div class="webpack"></div>

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

.webpack {
 background: url(../img/webpack.png) no-repeat center;
 height:500px;
}
.small-webpack {
 background: url(../img/small-webpack.png) no-repeat center;
 height:250px;
}

index.js 引入css

require('../css/index.css');

执行webpack指令

$ webpack

查看生成的目录结构

 

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

总结:

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

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

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

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

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

安装

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

使用(css为例)

var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
 module: {
  loaders: [
   { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
  ]
 },
 plugins: [
  new ExtractTextPlugin("styles.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的使用示例:

let ExtractTextPlugin = require('extract-text-webpack-plugin');

// 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

安装插件到项目

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

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

var webpack = require("webpack");
var path = require("path");
var srcDir = path.resolve(process.cwd(), 'src');
var nodeModPath = path.resolve(__dirname, './node_modules');
var pathMap = require('./src/pathmap.json');
var glob = require('glob')
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var entries = function () {
 var jsDir = path.resolve(srcDir, 'js')
 var entryFiles = glob.sync(jsDir + '/*.{js,jsx}')
 var map = {};

 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,0,'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]',
     'image?{bypassOnDebug:true, progressive:true,optimizationLevel:3,pngquant:{quality:"65-80",speed:4}}'
    ]
   },
   {
    test: /\.((ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9]))|(ttf|eot)$/,
    loader: 'url?limit=10000&name=fonts/[hash:8].[name].[ext]'
   },
   {test: /\.(tpl|ejs)$/, loader: 'ejs'},
   {test: /\.css$/, 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

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var extractCSS = new ExtractTextPlugin('css/[name].css?[contenthash]')
var cssLoader = extractCSS.extract(['css'])
var sassLoader = extractCSS.extract(['css', 'sass'])

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

注意事项:

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

output: {
 ......
 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 发布 前端自动化构建的项目模板

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


# webpack  # Loaders  # 模块加载器  # webpack静态资源处理  # 静态资源  # 详解webpack模块加载器兼打包工具  # webpack的CSS加载器的使用  # Vue CLI 中常用的加载器及其配置小结  # 加载  # 转成  # 进了  # 可以通过  # 对其  # 采用了  # 的是  # 文档  # 在这  # 把它  # 将其  # 然后再  # 重写  # 可选  # 为例  # 管理器  # 看一下  # 第三方  # 它将  # 创建一个 


相关文章: 如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  学校为何禁止电信移动建设网站?  全景视频制作网站有哪些,全景图怎么做成网页?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  建站之星免费版是否永久可用?  如何在阿里云香港服务器快速搭建网站?  建站主机选择指南:服务器配置与SEO优化实战技巧  安云自助建站系统如何快速提升SEO排名?  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?  开封网站制作公司,网络用语开封是什么意思?  建站之星后台密码遗忘或太弱?如何重置与强化?  怀化网站制作公司,怀化新生儿上户网上办理流程?  Python文件管理规范_工程实践说明【指导】  内网网站制作软件,内网的网站如何发布到外网?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  Android使用GridView实现日历的简单功能  如何通过cPanel快速搭建网站?  弹幕视频网站制作教程下载,弹幕视频网站是什么意思?  建站之星如何通过成品分离优化网站效率?  如何高效生成建站之星成品网站源码?  外贸公司网站制作哪家好,maersk船公司官网?  网站制作需要会哪些技术,建立一个网站要花费多少?  如何用PHP工具快速搭建高效网站?  C++中引用和指针有什么区别?(代码说明)  长沙企业网站制作哪家好,长沙水业集团官方网站?  制作表格网站有哪些,线上表格怎么弄?  如何快速搭建FTP站点实现文件共享?  如何通过远程VPS快速搭建个人网站?  高防服务器如何保障网站安全无虞?  非常酷的网站设计制作软件,酷培ai教育官方网站?  商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?  C++用Dijkstra(迪杰斯特拉)算法求最短路径  宝塔建站助手安装配置与建站模板使用全流程解析  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  历史网站制作软件,华为如何找回被删除的网站?  php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】  佛山网站制作系统,佛山企业变更地址网上办理步骤?  宿州网站制作公司兴策,安徽省低保查询网站?  网站制作的方法有哪些,如何将自己制作的网站发布到网上?  活动邀请函制作网站有哪些,活动邀请函文案?  建站之星ASP如何实现CMS高效搭建与安全管理?  定制建站哪家更专业可靠?推荐榜单揭晓  建站为何优先选择香港服务器?  如何在阿里云高效完成企业建站全流程?  建站之星多图banner生成与模板自定义指南  公司网站制作价格怎么算,公司办个官网需要多少钱?  企业网站制作公司网页,推荐几家专业的天津网站制作公司? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。