在自构建自己的个人页面的时候使用到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环境,所以如果要在配置里面用到全局变量,用函数返回

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

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(), //性能优化 高大上的可视化分析模块
],

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会报错。

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

{
"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.41.0配置一(基础配置webpack文件,入口出口,实现打包)

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

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

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

  4. thinkphp3.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多应用/项目配置技巧(使用同一配置文件)--(十六)

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

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

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

  9. ASP.NET Core 项目配置 ( Startup )(转载)

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

随机推荐

  1. Linux 7.x 防火墙&端口

    Linux 7.x 防火墙&端口 查看当前防火墙的状态: # firewall-cmd --state 也可以使用指令:systemctl status firewall.service 启动 ...

  2. ELK实时日志分析平台环境部署

    为什么要用到ELK一般我们需要进行日志分析场景是:直接在日志文件中 grep.awk 就可以获得自己想要的信息.但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档.文本搜索太慢怎么办 ...

  3. 递归算法+sql三种分页

    using Maticsoft.Common; using System; using System.Collections.Generic; using System.Data; using Sys ...

  4. Redmine(window7)安装

    首先要准备Ruby相关文件,Redmine是基于Ruby on rails开发的. 1.下载railsinstaller,我这时下载的版本是railsinstaller-2.2.1.exe,对应的官网 ...

  5. 20165305 《网络对抗技术》 Kali安装

    一.安装kali 在虚拟机中安装kali我参考了下面的网页,里面写的很全面,所以我就不重复了,我主要说一下kali里面的环境配置. 在虚拟机中安装kali linux 注意:输入用户和密码时,kali ...

  6. ABP入门系列之1——ABP总体介绍

    ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点, ...

  7. (2018干货系列二)最新HTML5学习路线整合

    怎么学HTML5 HTML5是万维网的核心语言,标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次重大修改,一方面提升了用户体验,另一方面HTML5技术跨平台,适配多终端,改变了传统开发者 ...

  8. C++隐藏任务栏图标

    在VC编程中,有时候我们需要将我们的程序在任务栏上的显示隐藏起来,我试过几种方法,下面我介绍一下我知道的三种方法. 第一种方法是设置窗口WS_EX_TOOLWINDOW扩展样式,通过在OnInitDi ...

  9. WindowsService调用API

    本文着重于WindowsServic如何调用API以及出现部分问题的解决方案 本文Windows Service 创建摘自JasperXu的博客   链接:http://www.cnblogs.com ...

  10. ltp-ddt nor qspi spi调试中需要修改的地方

    1 blk_device_dd_readwrite_test.sh before SRC_FILE="/home/root/srctest_file_${DEVICE_TYPE}_$$&qu ...