webpack系列目錄
webpack 系列 三:webpack 如何集成第三方js庫
webpack 系列 四:webpack 多頁面支持 & 公共組件單獨打包 
webpack 系列 五:webpack Loaders 模塊加載器
webpack 系列 六:前端項目模板-webpack+gulp實現(xiàn)自動構建部署
基于webpack搭建純靜態(tài)頁面型前端工程解決方案模板, 最終形態(tài)源碼見github: https://github.com/ifengkou/webpack-template
正文
Webpack將所有靜態(tài)資源都認為是模塊,比如JavaScript,CSS,LESS,TypeScript,JSX,CoffeeScript,圖片等等,從而可以對其進行統(tǒng)一管理。為此Webpack引入了加載器的概念,除了純JavaScript之外,每一種資源都可以通過對應的加載器處理成模塊。和大多數(shù)包管理器不一樣的是,Webpack的加載器之間可以進行串聯(lián),一個加載器的輸出可以成為另一個加載器的輸入。比如LESS文件先通過less-load處理成css,然后再通過css-loader加載成css模塊,最后由style-loader加載器對其做最后的處理,從而運行時可以通過style標簽將其應用到最終的瀏覽器環(huán)境。
一 常用loader
安裝css/sass/less loader加載器
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');執(zhí)行webpack指令
$ webpack
查看生成的目錄結構
 
 
其中并沒有css文件,css被寫入到了index.js中,index.js 部分截圖

總結:
圖片采用了url-loader加載,如果小于10kb,圖片則被轉化成 base64 格式的 dataUrl
css文件被打包進了js文件中
css被打包進了js文件,如果接受不了,可以強制把css從js文件中獨立出來。官方文檔是以插件形式實現(xiàn):文檔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])
ExtractTextPlugin.extract([notExtractLoader], loader, [options])
根據(jù)已有的loader,創(chuàng)建一個提取器(loader的再封裝)
多入口文件的extract的使用示例:
let ExtractTextPlugin = require('extract-text-webpack-plugin');// multiple extract instanceslet 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的路徑會出現(xiàn)問題,通過設置publicPath 解決,采用絕對路徑
output: { ...... publicPath: "/"},運行:
$ webpack
期望
運行webpack后的項目的目錄結構:
 
生成的 dist/index.html 自動引用了 index.css 和相關的js,由于設置了publicPath 所以相應的鏈接都采用了絕對路徑

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

結果:
最后,運行 webpack-dev-server 看一下運行結果:

總結
Webpack將所有靜態(tài)資源都認為是模塊,而通過loader,幾乎可以處理所有的靜態(tài)資源,圖片、css、sass之類的。并且通過一些插件如extract-text-webpack-plugin,可以將共用的css抽離出來
下篇介紹改進webpack.config.js:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點
疑難解答