记一次webpack4.x项目配置

时间:2022-02-05 11:39:36

在自构建自己的个人页面的时候使用到webpack4,遇到了一些问题,查看了大佬们的文章以及官方文档,在这里总结一下。

webpack比较基础的东西就不赘述了,代码里面的注释也会辅助说明,先看一下目录结构:

│  .babelrc
│ .gitignore
│ package-lock.json
│ package.json
│ README.en.md
│ README.md

├─build
│ webpack.common.js
│ webpack.dev.js
│ webpack.prod.js
│ webpack.rules.js

└─src
├─assets
│ test.json

├─common
│ ├─css
│ ├─fonts
│ ├─images
│ └─js
└─pages
├─my
│ index.html
│ index.js
│ index.styl

└─other
index.html
index.js
index.styl

这里目录结构导出如果有不知道的同学,其实很简单,windows命令 tree /f 导出当前目录包括文件夹名字,tree /f > catalog.txt 导入到一个txt文本。

1.webpack整体配置

像大部分同学的习惯一样,在build文件夹里面分为几个webpack配置,common基础公用配置,dev开发环境配置,prod生产环境配置,以及单独分离出来的rule配置各项loader。

//common
module.exports = (env) => {
return {
entry: {},
plugins: [],
optimization: {},
module: {}
}
};
//dev
module.exports = merge(common('development'), {
mode: 'development',
devtool: 'inline-source-map',
output: {},
devServer: {},
plugins: [],
});
//prod
module.exports = merge(common('production'), {
mode: 'production',
output: {},
plugins: [
],
});

这里webpack4 推荐用mode声明开发环境还是生产环境,这里是作为一个全局变量,而不是node环境,所以如果要在配置里面用到全局变量,用函数返回

记一次webpack4.x项目配置

这里我是直接定义的变量,然后在引用的时候传入参数,不是官方所定义的全局变量,其实这样写不是很好,既然分离了环境那就应该在不同的配置文件中写配置。

2.多页面entry配置和html模版插件

webpack里面的entry

    entry: {
// 多入口文件
my: [
'./src/pages/my/index.js',
],
other: [
'./src/pages/other/index.js',
]
},

在外部定义多个页面的信息,以及html-webpack-plugin模版插件的函数进行批量操作

/*可多页面配置*/
const htmlArray = [
{
_html: 'my',
title: '我的首页',
// chunks: ['my']
},
{
_html: 'other',
title: '其他',
// chunks: ['other']
}
];
// 获取html-webpack-plugin参数的方法
let getHtmlConfig = function (name, title, globalEnv) {
return {
template: `./src/pages/${name}/index.html`,
filename: `${name}.html`,
// favicon: './favicon.ico',
title: title,
inject: true,
hash: false, //开启hash ?[hash] /*chunk 里面配置的文件才会在html中引入,所以有其他引入的话要注意加上,
比如runtime和splitChunks里面的vendor等,建议不要这个,默认加载所有的*/
// chunks: chunks, minify: globalEnv === "development" ? false : {
removeComments: true, //移除HTML中的注释
collapseWhitespace: true, //折叠空白区域 也就是压缩代码
removeAttributeQuotes: true, //去除属性引用
},
};
};

在webpack plugin里面引入执行html模版

      //自动生成html模板
...htmlArray.map((element) => {
return new HtmlWebpackPlugin(getHtmlConfig(element._html, element.title, env));
}),

3.module.rules loader加载器

由于loader比较多,可以单独提取到一个配置文件

    css,css预处理器loader,MiniCssExtractPlugin是webpack4分离css的插件,后面再提到

  1.     {
    test: /\.(css|styl)$/,
    // 区别开发环境和生成环境
    /*用了MiniCssExtractPlugin,不要用style-loader,冲突*/
    use: env === "development" ?
    ["style-loader", "css-loader", "stylus-loader"] :
    [MiniCssExtractPlugin.loader, "css-loader", "stylus-loader"]
    },
  2.     {
    test: /\.js$/,
    exclude: "/node_modules/",
    use: [{
    loader: "babel-loader",
    options: {
    /*可使用禁止在每个文件注入runtime,避免文件多而大,采用babel-plugin-transform-runtime辅助提取引用
    * plugins: ['@babel/transform-runtime']*/ // 配置在 .babelrc 中,和browserslist
    // presets: ['@babel/preset-env']
    }
    }]
    },

    这里是base64转换和输入位置,更多配置可以看官网

  3.     {
    test: /\.(png|jpg|gif)$/,
    use: [{
    // url-loader包含file-loader
    loader: "url-loader",
    options: {
    limit: 5 * 1024, //小于5k时将会已base64位图片打包处理
    // 图片文件输出的文件夹
    outputPath: "images"
    }
    }]
    },

    字体和html的 loader

  4.     {
    test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
    limit: 10000,
    /*原来的名字和后缀*/
    name: '[name].[ext]',
    // 文件输出的文件夹
    outputPath: "fonts"
    }
    },
    {
    test: /\.html$/,
    // html中的img标签
    use: ["html-withimg-loader"]
    },

4. plugin

common 里面,第一个是html模版,上面讲过了,第二三个顾名思义。

    plugins: [

      //自动生成html模板
...htmlArray.map((element) => {
return new HtmlWebpackPlugin(getHtmlConfig(element._html, element.title, env));
}), // 消除冗余的css代码
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, "../src/pages/*/*.html"))
}), //静态资源输出
new CopyWebpackPlugin([{
from: path.resolve(__dirname, "../src/assets"),
to: './assets',
ignore: ['.*']
}]), ],

dev,这里官方提示使用这里完全启发devServer热更新,我没深入研究,同志们可以研究一下。

  plugins: [
//热更新,配合devserver服务完全启动HMR
new webpack.HotModuleReplacementPlugin(), // new BundleAnalyzerPlugin(), //性能优化 高大上的可视化分析模块
],

记一次webpack4.x项目配置

prod,清理dist的插件有一点小变动,提取css的插件官方建议被替代,以及仍然需要额外的插件压缩css

  plugins: [

    /*删除dist目录,2.0后默认了output的path,这里无需填写*/
new CleanWebpackPlugin({
root: path.resolve(__dirname, '../'), //根目录
// verbose Write logs to console.
verbose: true, //开启在控制台输出信息
}), /*webpack用这个代替ExtractTextPlugin,提取,开发环境我没分离*/
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].[contenthash].css',
// chunkFilename: '[id].[contenthash].css',
}),
//压缩css
new OptimizeCSSPlugin(), ],

5. 代码压缩和分离

    /*代码分离 压缩,webpack4x集成部分插件和选项*/
optimization: {
/*压缩js代码入口,是否开启minimizer,
例如TerserWebpackPlugin插件,性能比UglifyJSPlugin好
默认引入生产模式为true,所以不用操作,可以手动开启和调节minimizer选项*/
// minimize: false /*将运行时代码拆分为单独的块。
将其设置single为为所有块创建单个运行时包
单页面
runtimeChunk: 'single',
*/ /*多页面别名*/
runtimeChunk: {
name: entryPoint => `runtimechunk~${entryPoint.name}`
},
/*分离公共代码*/
splitChunks: {
/*缓存chunk 提取公共模块复用*/
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
},
},

6. 开发环境devServer

  devServer: {
contentBase: path.join(__dirname, "../dist"),
publicPath:'/',
host: "127.0.0.1",
port: "5199",
overlay: true, // 浏览器页面上显示错误
// open: true, // 开启浏览器 open: 'Google Chrome'
// stats: "errors-only", //stats: "errors-only"表示只打印错误:
hot: true, // 开启热更新
// compress: true, //开启gzip
},

7. 生产环境 output 输出

  output: {
path: path.resolve(__dirname, '../dist'),
// 打包多出口文件
// 生成 a.bundle.[hash].js b.bundle.[hash].js
// hash工程级整个是一样的,chunkhash模块级有依赖的文件是一样的,contenthash根据自身的内容生成hash,每个文件都不一样
filename: './js/[name].[contenthash].js',
publicPath: './'
},

8. js 语法和api转换编译

  开发依赖

"@babel/cli": "^7.2.3",
"@babel/core": "^7.3.4",
"@babel/plugin-transform-runtime": "^7.3.4",
"@babel/preset-env": "^7.3.4",
"babel-loader": "^8.0.5", 生产也需要的依赖
"dependencies": {
"@babel/polyfill": "^7.2.5",
"@babel/runtime": "^7.3.4"
}
其中runtime官方的说法是节约代码以及生成器语法的转换,如果不用这两个使用async和await会报错。

记一次webpack4.x项目配置记一次webpack4.x项目配置

然后在.babelrc中使用,关于 @babel/polyfill 的使用,这里配合 @babel/preset-env 有三种使用方式,这里usage会自动根据代码转换,安装后不要引入。

记一次webpack4.x项目配置

{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}

最后在package.json或者单独建立browserslist文件来限制浏览器版本和转换操作

"browserslist": [
"defaults",
"not ie < 11",
"last 2 versions",
"> 1%",
"iOS 7",
"last 3 iOS versions"
], 最后启动和大概测试了下,没发现什么问题。
由于时间和能力有限,可能有很多没考虑到,不够深入理解,还有一些冗余甚至错误的地方望各位大佬指正。

参考:

1,多页面配置,参考的是这位大佬的文章。https://segmentfault.com/a/1190000014984842

2,webpack官方文档,可以统一看一遍。https://webpack.js.org/plugins/mini-css-extract-plugin/

3,babel相关官方文档  https://babeljs.io/docs/en/babel-polyfill#docsNav

附:

1,在线配置webpack的页面,常用的依赖,插件和代码分割以及安装命令等。https://webpack.jakoblind.no/

time:2019-02-15

记一次webpack4.x项目配置的更多相关文章

  1. 在找一份相对完整的Webpack项目配置指南么?这里有

    Webpack已经出来很久了,相关的文章也有很多,然而比较完整的例子却不是很多,让很多新手不知如何下脚,下脚了又遍地坑 说实话,官方文档是蛮乱的,而且有些还是错的错的..很多配置问题只有爬过坑才知道 ...

  2. webpack4&period;41&period;0配置一(基础配置webpack文件,入口出口,实现打包)

    1.查看node.js版本.npm版本和webpack版本(使用webpack4时,请确保node.js的版本>=8.9.4) 2.我先重新卸载了webpack和webpack-cli(全局) ...

  3. Project server 2016 &OpenCurlyDoubleQuote;没有为此项目配置网站”错误处理

    问题: 没有为此项目配置网站. There is no site configured for this project 解决办法: 依次点击设置>PWA设置>连接到sharepoint网 ...

  4. thinkphp3&period;22 多项目配置

    1.index.php if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !'); // 开启调试 ...

  5. VS2010的项目配置

    一直对VS的项目配置都是不怎么了解的,以前用过点,半年不用后,什么都忘记了... 下面这个是免于输入过长的引用头文件的,比如:#include “D:/C++/curl-7.37.0/libcurl/ ...

  6. VC项目配置基础以及快捷键(收藏)

    来自http://blog.csdn.net/phunxm/article/details/5082488 一.IDE基础配置 1.字体 VC6中“Tools→Options→Format→Font” ...

  7. ThinkPHP多应用&sol;项目配置技巧(使用同一配置文件)--&lpar;十六&rpar;

    原文:ThinkPHP多应用/项目配置技巧(使用同一配置文件)--(十六) ThinkPHP多应用配置技巧(没有使用分组,这是通过入口文件产生的Home.Admin)----很实用! 比如:现在有Ho ...

  8. 理解 IntelliJ IDEA 的项目配置和Web部署

    1.项目配置的理解 IDEA 中最重要的各种设置项,就是这个 Project Structre 了,关乎你的项目运行,缺胳膊少腿都不行.最近公司正好也是用之前自己比较熟悉的IDEA而不是Eclipse ...

  9. ASP&period;NET Core 项目配置 &lpar; Startup &rpar;(转载)

    原文:https://www.twle.cn/l/yufei/aspnetcore/dotnet-aspnet-startup.html 由于是个人网站,怕没了,特意复制保存,个人觉得讲的非常透彻 前 ...

随机推荐

  1. 在 SharePoint Server 2016 本地环境中设置 OneDrive for Business

    建议补丁 建议在sharepoint2016打上KB3127940补丁,补丁下载地址 https://support.microsoft.com/zh-cn/kb/3127940 当然不打,也可以用O ...

  2. mydetails-yii1

    1.yii验证码多余的get a new code ,即使在main.php中配置了中文也是出现获取新图片,影响效果 需要把 <?php $this->widget('CCaptcha') ...

  3. 启用Win8&lpar;中文版&sol;核心版&rpar;中被阉割的远程桌面服务端

    Windows 8/8.1 标准版(中文版/核心版)中取消了远程桌面服务端,想通过远程连接到自己的电脑就很麻烦了,第三方远程桌面速度又不理想(如TeamViewer).通过以下方法可让系统恢复远程桌面 ...

  4. 源码分析之spring-JdbcTemplate日志打印sql语句

    对于开源的项目来说的好处就是我们遇到什么问题可以通过看源码来解决. 比如近期有个同事问我说,为啥JdbcTemplate中只有在Error的时候才打印出sql语句呢.我一想,这和log的配置有关系吧. ...

  5. jquery简单切换插件

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  6. maya&lowbar;help&lpar;&rpar;验证编程过程中模块导入的情况

    import rigLib reload(rigLib.base.control)spine = rigLib.base.control.Control( prefix = 'spine1') hel ...

  7. centos7 安装 redis4&period;0&period;8

    1.安装lrzsz yum install lrzsz -y 2.利用rz命令将window中从redis官网下载好的“redis-4.0.8.tar.gz” 拷贝到centos中 redis官网 : ...

  8. Mybatis in 查询

    1.先创建一个传参的工具类 import java.util.HashMap; /** * * ClassName: DataMap * @Description: 封装Map, * @date 20 ...

  9. OSX&colon; SSH密钥使用日记&lpar;1&rpar;

    大家都知道,一个悠久的历史故事,使用SSH密钥对就可以不用密码登陆远程计算机.经典资料也是不少,不过那些资料对新学者可是有点太不象人话了,不好理解.所以本文试图用更人性一点的语言解释,并演示如何在Ma ...

  10. 过滤4字节及以上的字符c&plus;&plus;实现

    这个是根据php的一个版本改的,用来处理utf-8编码的多字节字符,比如中文,俄文等等. #include <iostream> #include <string> int s ...