博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用webpack4打造自己的前端工作流
阅读量:4087 次
发布时间:2019-05-25

本文共 8186 字,大约阅读时间需要 27 分钟。

前言

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 // 删除空格      }    })  ]}复制代码

打包后的代码

      
webpack learn
复制代码

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模板文件

      
template file
hello template
复制代码

插件配置项

plugins: [  new HtmlWebpackPlugin({    filename: 'index.html',    template: './tmp/tmp.html'  })]复制代码

打包后生成的index.html

      
template file
hello template
复制代码

多页面

对于多页面一般会对应多个入口文件,不同的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对应的打包文件    })  ]}复制代码

运行结果

webpack learn
hello template
webpack learn
hello template
webpack learn
hello template
复制代码

内联

除了以链接的形式引入入口文件,也可以内联到页面中。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.jsimport '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.jsrequire('./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.jsrequire('./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('')}将相对路径包裹一次

复制代码

第三方库

比如说我们通过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')  }}复制代码

实用配置

最后基于上面的所有介绍,把所有的配置综合到一起。由于代码比较多,就不再这里展开了,我把示例代码放到了GitHub

参考文章

作者:wmui
链接:https://juejin.im/post/5b7f7bcf6fb9a019d137d06f
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
DirectX11 渲染——输入装配、绑定着色器、绘制
查看>>
游戏程序员养成计划
查看>>
3D数学 矩阵和线性变换之旋转
查看>>
3D数学 矩阵和线性变换之缩放
查看>>
3D数学 矩阵和线性变换之正交投影
查看>>
3D数学 矩阵和线性变换之镜像
查看>>
3D数学 矩阵和线性变换之切变
查看>>
DirectX11 着色器资源视图
查看>>
DirectX11 采样状态对象
查看>>
DirectX11 获得纹理描述
查看>>
DirectX11 常量缓存
查看>>
DirectX11 创建视图-投影矩阵
查看>>
DirectX11 混合状态
查看>>
DirectX11 动态缓存
查看>>
DirectX11 绘制字体
查看>>
DirectX11 输入设备——DirectInput检测鼠标、键盘状态
查看>>
设计模式 业务封装 & 紧耦合 vs. 松耦合 & 简单工厂模式
查看>>
UML 类图基本图示法
查看>>
Github免费账户使用”私有库“
查看>>
设计模式 策略模式
查看>>