【webpack系列】从零搭建 webpack4+react 脚手架(四)
经过三个章节的学习,你已经学会搭建了一个基于webpack4的react脚手架。如果要更改配置,比如,你希望把编译后的js文件和css文件等单独放dist下的static目录下,你想想,是不是有点麻烦。你要去浏览webpack的配置文件,找到哪些配置项,然后去更改它,我们希望有个参数配置文件,只要更改参数配置,而无需更改webpack的配置文件。
(1)在根目录创建config文件夹,在config文件夹内新建一个index.js文件,文件内容如下:
'use strict'
const path = require('path')
module.exports = {
dev: {
assetsSubDirectory: 'static',
assetsPublicPath: '/',
},
build: {
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
}
}
我们定义了一部分配置参数,顾名思义,dev属性下的参数配置是针对开发环境,build属性下的参数配置是针对生产环境的。其中,assetsRoot是编译后的文件存放根路径,assetsSubDirectory是资源文件编译后存放的文件夹名称,assetsPublicPath是公共的路径。
(2)修改webpack.base.conf.js,如下
const path = require('path');
const config=require('../config');
const APP_PATH = path.resolve(__dirname, '../app');
module.exports = {
entry: {
app: './app/index.js',
framework: ['react', 'react-dom'],
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
module: {
rules: [
{
test: /\.js?$/,
use: "babel-loader",
include: APP_PATH
}
]
}
};
注意:我们在webpack.base.conf.js内配置了filename,那么dev环境下默认使用该配置,可以删除webpack.dev.conf.js内关于output的配置。
(3)路径生成方法:
路径的配置需要由assetsPublicPath和assetsSubDirectory以及具体的子路径组成,我们写一个公共的方法来生成路径。无论是开发环境还是生产环境,我们都可以复用该方法。我们在build文件夹下建立一个utils.js文件。内容如下:
const path = require('path')
const config = require('../config')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
(4)修改webpack.prod.conf.js
在webpack.prod.conf.js页面头部引入
const config=require('../config');
const utils=require('./utils');
修改output属性的内容
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash:16].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
修改plugins内的相关配置:
new CleanWebpackPlugin([config.build.assetsRoot], { allowExternal: true }),
//导出css
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[hash].css'),
chunkFilename: utils.assetsPath('css/[id].[hash].css'),
}),
(5)执行编译命令查看
npm run build
查看编译后的文件是否放在static目录下了。你可以修改参数配置文件,然后试试看吧。
(1)index.html HTML模板的位置
在config.js文件的dev和build参数下都配置index属性:
index: path.resolve(__dirname, '../public/index.html'),
修改HtmlWebpackPlugin内template的值:
webpack.prod.conf.js的相关修改:
new HtmlWebpackPlugin({
template: config.build.index,
inject: 'body',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
}),
webpack.dev.conf.js的相关修改:
new HtmlWebpackPlugin({
template: config.dev.index,
inject: true
}),
(2)增加devServer 的配置
dev环境下,启动的端口号,代理相关,以及是否自动打开浏览器等等推荐可以放在参数配置文件内。
在config.js文件内增加相关配置参数:
proxyTable: {},
host: 'localhost',
port: ,
autoOpenBrowser: true,
修改webpack.dev.conf.js内的相关配置:
devServer: {
host: config.dev.host,
port: config.dev.port,
contentBase: path.join(__dirname, '../public'),
compress: true,
historyApiFallback: true,
hot: true,
https: false,
noInfo: true,
open: config.dev.autoOpenBrowser,
proxy: config.dev.proxyTable,
}
(1)前期准备,增加部分参数配置
修改config.js内的配置:
const path = require('path')
module.exports = {
base: {
// 是否开启cssModule
cssModule: true,
// cssModule排除的目录, 其他css库可以放这里
cssModuleExcludePath: /public/
},
dev: {
assetsSubDirectory: 'static',
assetsPublicPath: '/',
index: path.resolve(__dirname, '../public/index.html'),
proxyTable: {},
host: 'localhost',
port: ,
autoOpenBrowser: true,
// 是否生成sourceMap
cssSourceMap: true,
},
build: {
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
index: path.resolve(__dirname, '../public/index.html'),
// 是否生成sourceMap
productionSourceMap: true,
}
}
(2) 在utils.js内增加cssLoaders和styleLoaders方法:
exports.cssLoaders = function (options) {
options = options || {}
let cssLoader = {
loader: 'css-loader',
options: {
importLoaders: ,
sourceMap: options.sourceMap
}
}
if (options.cssModule) {
cssLoader.options.modules = true;
cssLoader.options.localIdentName = '[local]__[hash:7]';
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
function generateLoaders(loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
if (options.extract) {
return [MiniCssExtractPlugin.loader].concat(loaders)
} else {
return ['style-loader'].concat(loaders)
}
}
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less', { javascriptEnabled: true, indentedSyntax: true }),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
exports.styleLoaders = function (options) {
let output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
let loaderObj = {
test: new RegExp('\\.' + extension + '$'),
use: loader,
}
if (options.cssModule) {
loaderObj.exclude = options.cssModuleExcludePath;
}
output.push(loaderObj)
}
if (options.cssModule) {
options.cssModule = false
const cssModuleLoaders = exports.cssLoaders(options)
for (const extension in cssModuleLoaders) {
const cssModuleLoader = cssModuleLoaders[extension]
let cssModuleLoaderObj = {
test: new RegExp('\\.' + extension + '$'),
use: cssModuleLoader,
}
cssModuleLoaderObj.include = options.cssModuleExcludePath;
output.push(cssModuleLoaderObj)
}
}
return output
}
(3) 在webpack.prod.conf.js内使用
确认是否引入了utils,如果没有引入,在页面上方增加代码:
const utils=require('./utils');
修改 module内的rules属性:
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true,
cssModule:config.base.cssModule,
cssModuleExcludePath:config.base.cssModuleExcludePath
})
执行编译查看:
npm run build
(4) 在webpack.dev.conf.js内使用
确认是否引入了utils,如果没有引入,在页面上方增加代码:
const utils=require('./utils');
修改 module内的rules属性:
rules: utils.styleLoaders({
sourceMap: config.dev.cssSourceMap,
usePostCSS: true,
cssModule:config.base.cssModule,
cssModuleExcludePath:config.base.cssModuleExcludePath
})
执行dev命令试试看
npm run dev
下一节会对 如果对编译后的文件进行gzip压缩,如何让开发环境的控制台输出更加高逼格,如何更好的对编译后的文件进行bundle分析等问题展开讨论。
【webpack系列】从零搭建 webpack4+react 脚手架(四)的更多相关文章
- 【webpack系列】从零搭建 webpack4+react 脚手架(一)
搭建一个React工程的方式有很多,官方也有自己的脚手架,如果你和我一样,喜欢刨根究底,从零开始自己一行一行代码创建一个React脚手架项目,那你就来对地方了.本教程是针对React新手,以及对web ...
- 【webpack系列】从零搭建 webpack4+react 脚手架(三)
本章节,我们对如何在脚手架中引入CSS,如何压缩CSS,如何使用CSS Modules,如何使用less,如何使用postcss等问题进行展开学习. 1 支持css (1)在app目录,新建一个css ...
- 【webpack系列】从零搭建 webpack4+react 脚手架(二)
html文件如何也同步到dist目录?bundle.js文件修改了,万一被浏览器缓存了怎么办?如何为导出的文件加md5?如何把js引用自动添加到html?非业务代码和业务代码如何分开打包?如何搭建开发 ...
- 【webpack系列】从零搭建 webpack4+react 脚手架(五)
本章节,我们一起来探讨以下问题:如何对编译后的文件进行gzip压缩,如何让开发环境的控制台输出更加高逼格,如何更好的对编译后的文件进行bundle分析等. 1 gzip压缩 如果你想节省带宽提高网站速 ...
- 从零搭建Spring Boot脚手架(1):开篇以及技术选型
1. 前言 目前Spring Boot已经成为主流的Java Web开发框架,熟练掌握Spring Boot并能够根据业务来定制Spring Boot成为一个Java开发者的必备技巧,但是总是零零碎碎 ...
- 初探webpack之从零搭建Vue开发环境
初探webpack之搭建Vue开发环境 平时我们可以用vue-cli很方便地搭建Vue的开发环境,vue-cli确实是个好东西,让我们不需要关心webpack等一些繁杂的配置,然后直接开始写业务代码, ...
- 从零搭建Spring Boot脚手架(2):增加通用的功能
1. 前言 今天开始搭建我们的kono Spring Boot脚手架,首先会集成Spring MVC并进行定制化以满足日常开发的需要,我们先做一些刚性的需求定制,后续再补充细节.如果你看了本文有什么问 ...
- 从零搭建Spring Boot脚手架(3):集成mybatis
1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文集成了一些基础的功能,比如统一返回体.统一异常处理.快速类型转换.参数校验等常用必备功能,并编写了一些单元测试进行验证,今天 ...
- 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper
1. 前言 今天继续搭建我们的kono Spring Boot脚手架,上一文把国内最流行的ORM框架Mybatis也集成了进去.但是很多时候我们希望有一些开箱即用的通用Mapper来简化我们的开发.我 ...
随机推荐
- SpringMVC 监听文件上传进度
Spring MVC 监听文件上传进度 具体实现分三个步骤: 接管CommonsMultipartResolver,重写针对文件上传的请求. 在第一步中写入监听,以获取上传进度. 修改上传部分的配置文 ...
- 升级AndroidStudio3.4问题汇总
1.Could not get unknown property 'bootClasspath' for object of type org.gradle.api.tasks.compile.Com ...
- (二叉树 递归) leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal
Return any binary tree that matches the given preorder and postorder traversals. Values in the trave ...
- C语言 内存管理(转)
转自 https://blog.csdn.net/u011616739/article/details/61621815 C语言 内存管理 1.内存分区 C源代码进过预处理.编译.汇编和链接4步生成 ...
- hadoop记录-hadoop常用
1.hdfs目录配额 #设置配额目录hdfs dfsadmin -setSpaceQuota 10T /user/hive/warehouser/tmp查看配额目录信息hdfs dfs -count ...
- hadoop记录-浅析Hadoop中的DistCp和FastCopy(转载)
DistCp(Distributed Copy)是用于大规模集群内部或者集群之间的高性能拷贝工具. 它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成. 它把文件和目录的列表作为ma ...
- 微信小程序button组件样式
点击微信按键组件才能出授权,所以自定义样式就是必须的了,来自网友的帮助,如下图 <button class='btn1' open-type='contact'> <image cl ...
- AtCoder Grand Contest 030题解
第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...
- 题解:[GXOI/GZOI2019]与或和
开始完全没思路 在洛谷看到样例一,突发奇想,决定先做一下元素只有0/1的情况 发现子任务1是全1子矩阵 子任务2是总子矩阵个数减去全0子矩阵 发现全0/1矩阵可以构造单调栈解决.具体做法:前缀和求出每 ...
- Request method 'POST' not supported解决办法
(1)考虑拦截器是否将该链接拦截