Webpack常见静态资源处理

网友投稿 493 2023-05-03


Webpack常见静态资源处理

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

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])

id Unique ident for this plugin instance. (For advanded usage only, by default automatic generated)

filename the filename of the result file. May contain [name], [id] and [contenthash].

[name] the name of the chunk

[id] the number of the chunk

[contenthash] a hash of the content of the extracted file

options

allChunks extract fromall additional chunks too (by default it extracts only from the initial chunk(s))

disable disables the plugin

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

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

notExtractLoader (可选)当css没有被抽离时,加载器不应该使用(例如:当allChunks:false时,在一个additional 的chunk中)

loader 数组,用来转换css资源的加载器s

options

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]wJcdnptJ',

'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

期望

css单独抽离,打包成单独的css文件

html自动引用css文件

小于10k的图片,转成base64 格式的 dataUrl

webpack.png 会被压缩,减少文件大小

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

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

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

结果:

css单独打包到css目录

html自动注入了link 标签

small-webpack.png 小于10k,被打包进了index.css

webpack.png 由原来的50+k 被压缩成 10- k

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

总结

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

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

区分开发环境和生产环境

集成 gulp 实现自动构建打包部署

github 发布 前端自动化构建的项目模板


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Kotlin 基础教程之注解与java中的注解比较
下一篇:Java Process详解及实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~