【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来简化我们的开发.我 ...
随机推荐
- 微信小程序之:wepy框架
1.介绍 WePY 是 腾讯 参考了Vue 等框架对原生小程序进行再次封装的框架,更贴近于 MVVM 架构模式, 并支持ES6/7的一些新特性. 2.使用 npm install -g wepy-cl ...
- 谈谈JavaScript中继承方式
聊一聊js中的继承 一.简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型 父级构造函数 function Parent(param) { this.name = 'parent' ...
- 【转】BTree,B-Tree,B+Tree,B*Tree
B树: 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: ...
- Visual Studio Code 背景色自定义
1 寻找主体配置文件:默认的颜色主题配置文件都位于$RELEASE/resources/app/extensions目录中.以theme-开头的目录即为颜色主题配置(事实上,其中有些是文件图标主题). ...
- Springboot集成Spring Batch
Spring官网 (https://spring.io/projects/spring-batch#overview)对Spring Batch的解释: 一个轻量级的.全面的批处理框架,用于开发对企 ...
- Jupyter Notebook 的安装使用以及 tree 路径变更
由于最近开始学习 Python,进而接触到一个十分强大的交互式编辑器 — Jupyter Notebook,用起来也非常顺手,于是记录一下相关的使用过程. 一.安装 Python: ①首先前往 pyt ...
- 【转】Redis学习笔记(五)如何用Redis实现分布式锁(2)—— 集群版
原文地址:http://bridgeforyou.cn/2018/09/02/Redis-Dsitributed-Lock-2/ 单机版实现的局限性 在上一篇文章中,我们讨论了Redis分布式锁的实现 ...
- MVC系统过滤器 OutputCacheAttribute
命名空间: System.Web.Mvc程序集: System.Web.Mvc(在 System.Web.Mvc.dll 中) 一.MVC缓存简介 缓存是将信息(数据或页面)放在内存中以避免频繁的 ...
- 怎样解决canvas 插件 和html 页面中的事件冲突问题 ?
很简单 ,在html 执行事件所在的div中 设置 position:relative;
- Luogu P1082 同余方程(NOIP 2012) 题解报告
题目传送门 [题目大意] 求关于x的同余方程 ax≡1(mod b)的最小整数解. [思路分析] 由同余方程的有关知识可得,ax≡1(mod b)可以化为ax+by=1,此方程有解当且仅当gcd(a, ...