内容简介:webpack4发布已经有一段时间了,我在实践的过程中发现,很多项目配置在webpack3下工作正常,但是升级到webpack4直接就崩了,如果想要webpack4正常工作,很多插件也需要升级到新版。下面是我使用webpack4配置的一个学习案例,包含了日常开发的常用配置项,比如多入口文件配置、模板文件自定义、版本号控制、js和css分离、css自动添加前缀、scss转css、图片及字体文件的处理、babel编译JS语法和API等等当我们修改代码后,需要重新打包文件,这时候为了避免浏览器缓存,往往需要为文
webpack4发布已经有一段时间了,我在实践的过程中发现,很多项目配置在webpack3下工作正常,但是升级到webpack4直接就崩了,如果想要webpack4正常工作,很多插件也需要升级到新版。下面是我使用webpack4配置的一个学习案例,包含了日常开发的常用配置项,比如多入口文件配置、模板文件自定义、版本号控制、js和css分离、css自动添加前缀、scss转css、图片及字体文件的处理、babel编译JS语法和API等等
版本号
当我们修改代码后,需要重新打包文件,这时候为了避免浏览器缓存,往往需要为文件添加一个版本号
var webpack = require('webpack'); var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, plugins: [ new HtmlWebpackPlugin({ inject:'body', // 插入位置 favicon: './favicon.ico', // icon图标 title: 'webpack learn', // 生成的html文件的标题 filename: 'index.html', // 生成的html文件名称 minify:{ removeComments: false, // 删除注释 collapseWhitespace: false // 删除空格 } }) ] } 复制代码
打包后的代码
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>webpack learn</title> <link rel="shortcut icon" href="favicon.ico"> </head> <body> <script type="text/javascript" src="main.js?f8f60ca3f6ee44382620"></script></body> </html> 复制代码
html-webpack-plugin这个插件会生成一个名为index.html、标题是 webpack learn
的文件,并且自动把打包后的文件插入到html中。如果不配置这个插件,filename的默认值就是 index.html
,title默认是 Webpack APP
inject表示插入的位置,默认是 body
,可选值 head
favicon表示可以添加一个icon图标
minify表示对压缩文件,removeComments和collapseWhitespace的默认值都是false
模板文件
html-webpack-plugin插件可以使用模板文件,这样我们就可以自定义一个html文件,然后让这个插件把打包后的文件自动插入到模板文件中
tmp/tmp.html模板文件
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>template file</title> <body> <div>hello template</div> </html> 复制代码
插件配置项
plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', template: './tmp/tmp.html' }) ] 复制代码
打包后生成的index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>template file</title> <body> <div>hello template</div> </html> <script type="text/javascript" src="main.js?b321307e65d6b0fbee0b"></script> 复制代码
多页面
对于多页面一般会对应多个入口文件,不同的html页面输出对应不同的入口文件,html-webpack-plugin插件支持配置多页面。多页面需要配置chunks和excludeChunks,chunks表示所包含的入口文件,excludeChunks表示要排除的入口文件
var webpack = require('webpack'); var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { a: './src/main-a.js', b: './src/main-b.js', c: './src/main-c.js' }, output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, plugins: [ new HtmlWebpackPlugin({ filename: 'a.html', template: './tmp/tmp.html', chunks: ['a'] // 加载a对应的打包文件 }), new HtmlWebpackPlugin({ filename: 'b.html', template: './tmp/tmp.html', chunks: ['b'] // // 加载b对应的打包文件 }), new HtmlWebpackPlugin({ filename: 'c.html', template: './tmp/tmp.html', excludeChunks: ['a', 'b'] // 加载非a、b对应的打包文件 }) ] } 复制代码
运行结果
<!-- a.html --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>webpack learn</title> <body> <div>hello template</div> </html> <script type="text/javascript" src="a.js?82a9a04389852053c167"></script> <!-- b.html --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>webpack learn</title> <body> <div>hello template</div> </html> <script type="text/javascript" src="b.js?82a9a04389852053c167"></script> <!-- c.html --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>webpack learn</title> <body> <div>hello template</div> </html> <script type="text/javascript" src="c.js?82a9a04389852053c167"></script> 复制代码
内联
除了以链接的形式引入入口文件,也可以内联到页面中。html-webpack-inline-source-plugin插件专门用来处理入口文件内联的
var webpack = require('webpack'); var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, plugins: [ new HtmlWebpackPlugin({ inlineSource: '.(js|css)$' // 所有的js和css文件内联引入 }), new HtmlWebpackInlineSourcePlugin() ] } 复制代码
babel
babel可以把es最新标准的代码转为es5代码,首先需要安装babel-core核心程序,及babel-loader
npm i babel-loader babel-core -D 复制代码
由于ES每年会发布一个新版本,所以在进行转换时,需要选择从哪个标准进行转换,可供选择的有'es2015'、'es2016'、'es2017'、'latest'、'env'等多个不同的标准。
babel-preset-env标准是使用最多的,babel-preset-env在没有任何配置选项的情况下,与 babel-preset-latest(或者babel-preset-es2015,babel-preset-es2016和babel-preset-es2017一起)的行为完全相同
npm i babel-preset-env -D 复制代码
var webpack = require('webpack'); var path = require('path'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, module: { rules:[{ test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory: true } } }] } } 复制代码
rules属性中配置的exclude表示 node_modules
文件夹不需要babel进行转换。也可以配置一个include选项,比如 include: path.resolve(__dirname, 'src')
,表示只有src文件夹中的文件需要转换
cacheDirectory选项的默认值是false,设置为true将缓存 loader 的执行结果,加快编译速度
API转换
babel默认只转换JavaScript语法,对于新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等是不会转换的。如果需要转换API,需要使用babel-polyfill,babel-polyfill是一个全局垫片
npm i babel-polyfill -D 复制代码
入口文件引入babel-polyfill
// main.js import 'babel-polyfill'; let set = new Set([1,2,3]); 复制代码
babel-polyfill是一个全局垫片,开发中更常用的是babel-plugin-transform-runtime这个局部垫片,因为它可以使包的体积更小
npm i babel-plugin-transform-runtime babel-runtime -D 复制代码
var webpack = require('webpack'); var path = require('path'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, module: { rules:[{ test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['env'], cacheDirectory: true, plugins: ['transform-runtime'] } } }] } } 复制代码
CSS
处理css会用到css-loader和style-loader,css-loader用于读取并加载css文件,style-loader将它插入到页面中
// main.js require('./assets/styles/cssdemo.css'); 复制代码
var webpack = require('webpack'); var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, module: { rules:[{ test: /\.css$/, use: ['style-loader', 'css-loader'] }] }, plugins: [ new HtmlWebpackPlugin({}) ] } 复制代码
自动前缀
由于各大浏览器对CSS兼容性不同,部分CSS特性需要加上浏览器前缀才能正常工作,postcss-loader可以帮我们自动完成加前缀的工作
npm i postcss-loader autoprefixer postcss-import -D 复制代码
module: { rules: [{ test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { importLoaders: 1 } }, { loader: 'postcss-loader', options: { plugins: [ require('postcss-import'), // 解决css中import其他css require('autoprefixer') ] } } ] }] } 复制代码
sass
需要安装sass-loader及node-sass。
npm i sass-loader node-sass -D 复制代码
module: { rules: [{ test: /\.scss$/, use: ['style-loader','css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] } }, 'sass-loader' ] }] } 复制代码
分离css
默认情况下,CSS会被打包到入口JS文件中。如果需要把CSS分离出来,需要使用extract-text-webpack-plugin插件
npm i extract-text-webpack-plugin@next -D 复制代码
var webpack = require('webpack'); var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: './src/main.js', output: { path: path.join(__dirname, 'dist'), filename: '[name].js?[hash]' }, module: { rules: [{ test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] } }, 'sass-loader' ] }) }] }, plugins: [ new HtmlWebpackPlugin({}), new ExtractTextPlugin('main.css') ] } 复制代码
图片资源
webpack处理图片、字体、音乐、视频等资源时,需要安装file-loader
npm i file-loader -D 复制代码
// main.js require('./assets/styles/cssdemo.css'); 复制代码
/* cssdemo.css */ body { background: url('../images/dog.jpg') no-repeat; } h1 { color: red; } 复制代码
module: { rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/, loader: 'file-loader' }, { test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/, loader: 'file-loader', query: { name: '[name].[ext]?[hash]' } } ] } 复制代码
如果是在html模板中,通过img标签引入图片,需要使用 ${require('')}
将相对路径包裹一次
<img src="${require('../src/images/dog.jpg')}" alt=""> 复制代码
第三方库
比如说我们通过npm安装了jQuery,只需要通过provide-plugin插件就可以自动加载模块,而不必到处 import 或 require
npm i provide-plugin -D 复制代码
var ProvidePlugin = require('provide-plugin'); plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] 复制代码
在项目中使用
console.log($('#box'), jQuery('#box')) 复制代码
如果是把jQuery保存到了本地,可以通过设置别名来引用
resolve:{ alias:{ jQuery$: path.resolve(__dirname,'src/libs/jquery.min.js') } } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端工程工作流规范
- 前端工作流中的hooks
- gulp打造前端自动化工作流
- Gulp4 前端自动化工作流配置
- 前端工程化:围绕Jenkins打造工作流的过程
- LegoFlow 开源 v2.0 版本,前端工作流客户端
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。