Closed Superman-wc closed 7 years ago
好,下个版本。
如果可以的话, 支持hash 后,在build 后 集成 处理html文件中对js,css文件引用的路径修改,以前使用atool-build 时,都是用gulp 处理,,感觉只是光有hash还是很不完美的!
+1
+1
+1
+1
Workaround:
npm i -D ejs-loader html-webpack-plugin webpack-chunk-hash
无需安装 extract-text-webpack-plugin
因为 roadhog 已经带了 1.0.1 版,如果自己安装了 2.x 版反而可能出问题。需要额外安装 ejs-loader
因为 webpack 配置里会用到
const fs = require('fs')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const WebpackChunkHash = require('webpack-chunk-hash')
module.exports = function (config, env) {
config.module.loaders[0].exclude.push(/\.ejs$/) // 注 1
if (env === 'production') {
config.output.filename = '[name].[chunkhash].js'
config.output.chunkFilename = '[chunkhash].async.js'
config.plugins[3] = new ExtractTextPlugin('[contenthash:20].css') // 注 2
config.plugins.push(
new HtmlWebpackPlugin({
template: 'ejs!src/index.ejs', // 注 3
inject: true,
minify: { collapseWhitespace: true },
production: true,
}),
new WebpackChunkHash({ algorithm: 'md5' })
)
} else {
config.plugins.push(
new HtmlWebpackPlugin({
template: 'ejs!src/index.ejs',
inject: true,
}),
)
}
return config
}
[1] roadhog 默认配置把非 特定格式 的文件都用 url-loader
去加载,但是 html-webpack-plugin
需要的 ejs
文件会变成 base64 编码,所以要把 ejs
格式加入 loader 白名单,参考
[2] 覆盖 roadhog 的 配置
[3] roadhog 对 html 默认用的 file-loader,这里的 html-webpack-plugin
需要读取其内容作为模板,所以换成 ejs,也就不再需要 index.html
{
"env": {
"production": {
"publicPath": "https://cdn.example.com/"
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
</head>
<body>
<div id="root"></div>
</body>
</html>
去掉 import './index.html'
(如果有的话)
这样就同时兼顾了开发环境和部署环境使用同一套 html 入口,并且开发环境使用本地文件,部署环境使用按照文件内容 MD5 命名了的 CDN 文件(方便缓存控制)
参考
+1
@mdluo 你这个方法试过了吗?我用了一下,报错:
You may need an appropriate loader to handle this file type.
@varrant 肯定试过啊,我目前项目里就是这样用的。你看看是不是没装 ejs-loader
@mdluo 在roadhog里面装ejs-loader吗?还是全局装ejs-loader?还是在项目里面装?
@varrant 我更新了原文,加了说明和 CDN 的配置
@mdluo thanks very much ....遇到很多坑,终于成功了。cdn功能还未尝试,准备明天尝试。。 @sorrycc 不实现hash功能,是不是阿里已经有一套结合cdn的实现方式呢? @pigcan 我看了atool-build 也并未实现hash功能,但是,我用atool-build也能构建roadhog项目,那么roadhog和atool-build是不是又一定的联系呢? thanks
@mdluo
else {
config.plugins.push(
new HtmlWebpackPlugin({
template: 'ejs!src/index.ejs',
inject: true,
}),
)
}
这一句我没加,但是我在index.js中同时也引入了index.html
为什么这么做,因为我加上这句话,有问题,报错。
我又更新了回复,因为我之前的写法有个问题, chunk 文件不会从 CDN 地址去读
现在直接用 .roadhogrc
暴露出来的配置项 publicPath
去配置 CDN 地址,直接用 HtmlWebpackPlugin 的 inject
请问这个功能加上去了吗? 我是使用dva-cli生成的项目,假如还没有这项功能,能不能提供一个临时的解决方法?
说好的下个版本呢。。。
说好的下个版本呢。。。 我也是学@mdluo一样去改webpack.config.js了
现在主要还是能不能提供一个临时的解决办法,使用dva-cli生成的项目,现在build出来的文件会被缓存,连webpack.config.js都没有,表示很无奈。迫切希望能提供一个解决办法
@mdluo
补充一下:如果 .roadhogrc 启用了 "multipage": true
选项,那么按照你的配置生成的 JavaScript 公共文件名仍然是不带 hash 的 common.js。
要在 JavaScript 公共文件名中带上 hash,需要在你的 webpack.config.js 文件的“注 2”后添加以下语句:
const webpack = require('webpack')
// Override roadhog config
// https://github.com/sorrycc/roadhog/blob/master/src/config/webpack.config.prod.js#L199-L202
for (let plugin, i = 0, l = config.plugins.length; i < l; i++) {
plugin = config.plugins[i]
if (plugin instanceof webpack.optimize.CommonsChunkPlugin) {
config.plugins[i] = new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'common.[chunkhash].js'
})
break
}
}
麻烦问一下,下个版本好了吗?还是需要自己手工修改源码吗?
说好的下个版本呢。。。
说好的下个版本呢、。。
有点搞不懂如果要用webpack来解决问题,为什么还要用roadhog?直接用webpack集成就好了啊
@Nick290 同感
感觉作者把webpack封装了一遍,却又砍掉了很多常用功能 按照作者所说 如果roadhog的特色是 MOCK 和HMR ,何必封死webpack的功能, 给一份配置好的默认配置文件不就结了。 带着枷锁跳舞 sad :(
v1.0.1 版本, 配置 multipage 为 true 时候会输出如下的 js 。
<script type="text/javascript" src="undefined"></script><script type="text/javascript" src="/index.js"></script>
@mdluo 请教如何在roadhog开启hash之后, 来自动根据加的 hash 来引入对应的 css 和 js 并生成 html 文件
@weishijun14 加入html.ejs文件, 就可以自动加入带hash的js了
打开hash功能, 加入index.ejs后, build是没问题. 但是本地调试, 也就是npm start会报错
webpack-internal:///6:1 Uncaught ReferenceError: roadhog is not defined
at eval (webpack-internal:///6:1)
at Object.<anonymous> (index.js:838)
at __webpack_require__ (index.js:706)
at fn (index.js:112)
at eval (webpack-internal:///2:1)
at Object.<anonymous> (index.js:818)
at __webpack_require__ (index.js:706)
at fn (index.js:112)
at eval (webpack-internal:///60:12)
at Object.<anonymous> (index.js:1145)
index.ejs
, 还是用原来的index.html
, 这样也可以用0.6.0版本加入的dll功能 ,加快本地调试速度.npm run build
这样做好麻烦啊, 还要手动改文件,有没有更好的办法? 按照高票答案 @mdluo 的方法, 是可以兼顾本地调试和正式环境的 ,但1,0的版本怎么弄啊?
所以,问题是 index.ejs
没有自动引入 dll 文件?
@holynova 请问ejs文件是放在哪个目录下面?如果是多页面的话roadhogrc 如何配置?
@acwong00 V1.1.0 release log mentioned:
支持 HtmlWebpackPlugin,基于约定,存在 src/index.ejs 即开启此功能 (#356)
so add the ejs file under src folder
我也来贴贴我的配置把.
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = function (webpackConfig, env) {
// 我的项目里,使用了jquery
if (!Array.isArray(webpackConfig.module.rules)) {
webpackConfig.module.rules = [];
}
webpackConfig.module.rules.push({
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: '$',
}],
});
// 使用html-webpack-plugin来处理html文件
webpackConfig.plugins.push(
new HtmlWebpackPlugin({
template: 'public/index.html',
inject: true,
}),
);
// 下面这部分代码,是把file-loader给删掉,因为我们现在用了
// HtmlWebpackPlugin来处理html文件
let rules = webpackConfig.module.rules;
let idx = -1;
for (let i = 0; i < rules.length; i++) {
if (rules[i].test) {
if (rules[i].test.toString() === '/\\.html$/') {
idx = i;
}
}
}
rules.splice(idx, 1);
if (env === 'production') {
webpackConfig.output.publicPath = '/public/';
} else {
// 我发现,如果在dev环境下,设置了publicPath,那么会导致文件找不到
// webpackConfig.output.publicPath = '/public/';
}
return webpackConfig;
};
我的这个配置呢,可以在build的时候让静态文件的路径加上/public
前缀,不过在开发环境下,启动dev server
的时候,我发现就不能再设置publicPath
了,会导致静态文件找不到, 有别的什么办法可以解决这个问题吗?
roadhog打包出来的index.js有720kb,马上功能迭代了肯定会越来越大,请问有压缩的方法吗,尝试了网上所说的几种配置都不行
@manuo123 没做 commonChunk 抽取吗?你的比较大是不是把 react/react-dom 等都打进 index 里了。如果你在用较新版本的 roadhog 的话,可以这样:
externals: {
'@antv/data-set': 'DataSet',
'bizcharts': 'BizCharts',
'react': 'window.React',
},
这样这些不太变的第三方库,在入口HTML里面单独引入,每次迭代的时候基本上就只有你业务代码了所在的 chunk 了。
@xiaosansiji 你好,谢谢你的解答,请问能否提供一个具体的webpack配置的demo
@manuo123 大概这样,更多设置还是参考 roadhog 的文档吧,我的 roadhog 版本是 2.2.0
/.webpackrc.js
const path = require('path');
export default {
entry: 'src/index.js',
extraBabelPlugins: [
'transform-decorators-legacy',
['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
],
env: {
development: {
extraBabelPlugins: ['dva-hmr'],
},
},
// 后期 monitor、svc 等各站点共享 cdn 内的公共 js 资源
externals: {
'@antv/data-set': 'DataSet',
bizcharts: 'BizCharts',
rollbar: 'rollbar',
},
alias: {
components: path.resolve(__dirname, 'src/components/'),
layouts: path.resolve(__dirname, 'src/layouts/'),
utils: path.resolve(__dirname, 'src/utils/'),
},
ignoreMomentLocale: true,
theme: './src/theme.js',
html: {
template: './src/index.ejs',
},
disableDynamicImport: true,
publicPath: '/',
hash: true,
proxy: {
...
}
};
@xiaosansiji 感谢
@xiaosansiji 请问要配打包文件的目录要怎么配呢? 默认是在dist 目录下,现在我想改成在 dist/xxxx目录下。
@tang-yue
增加配置outputPath: 'dist/xx',
结果:
这是 webpack 提供的接口,详情建议看下这里
@xiaosansiji 谢谢这个问题我已经解决了。请问我现在想改变引用js的url, 现在是域名/index.js ,我想变成 域名/xxxx/index.js , 请问应该如何修改呢。我尝试修改publicPath 但是,会导致本地访问页面,出现Cannot GET 路径名 , 找不到我项目里的路径。请问你知道应该怎么改吗?
@tang-yue 用下env 配置,区分开发环境和生产环境就可以了
@xiaosansiji 十分感谢,目前项目在测试环境和本地环境都可以运行了。
各位大佬, 我按照你们讨论的写法如下写了,但是打包出来的文件名还是没有处理过的。配置如下: .roadhogrc:
{
"entry": "src/index.js",
"hash" : true,
"env": {
"development": {
"extraBabelPlugins": [
"dva-hmr",
"transform-runtime",
["import", { "libraryName": "antd", "style": "css" }]
]
},
"production": {
"extraBabelPlugins": [
"transform-runtime",
["import", { "libraryName": "antd", "style": "css" }]
]
}
}
}
已经在src下创建index.ejs的文件
package.json:
{
"private": true,
"scripts": {
"start": "roadhog server",
"build": "roadhog build",
"lint": "eslint --ext .js src test",
"precommit": "npm run lint"
},
"dependencies": {
"antd": "^3.7.3",
"dva": "^2.3.1",
"rc-bmap": "^0.1.8",
"react": "^16.2.0",
"react-clamp-lines": "^1.1.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"babel-plugin-dva-hmr": "^0.3.2",
"babel-plugin-import": "^1.8.0",
"eslint": "^4.14.0",
"eslint-config-umi": "^0.1.1",
"eslint-plugin-flowtype": "^2.34.1",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.1.0",
"husky": "^0.12.0",
"redbox-react": "^1.4.3",
"roadhog": "^2.0.0"
}
}
但是结果依旧没有进行hash,如下:
加了 src/index.ejs
修改了.webpackrc.js 的配置:
hash: true,
html: { "template": "./src/index.ejs" },
就能用了
当前版本 "roadhog": "^2.4.5"
看了一下config 中的文件, 生产环境中不支持 hash 文件名啊,,希望赶紧支持起来哦!