Nix*_*Nix 5 webpack ionic2 ionic-cli
我们有一个 Ionic 2 应用程序,它既可以本地部署,也可以部署到网络上。构建时我使用npm run build --prod --release. 这只是包装ionic build.
我正在尝试更新我们的构建过程,以便能够交换main.js.index.html 中的默认值
所以我希望能够更改此文件:
<script src="build/main.js"></script>
Run Code Online (Sandbox Code Playgroud)
与(自动生成的哈希)
<script src="build/main.7b297e8f7d1c2760a1bc.js"></script>
Run Code Online (Sandbox Code Playgroud)
第 1 步是生成文件。通过使用 webpack output.filename 设置,我能够在每次构建时成功生成正确的文件。
module.exports = {
entry: [process.env.IONIC_APP_ENTRY_POINT, './web.config', './src/ai.min.js'],
output: {
path: '{{BUILD}}',
filename: '[name].[chunkhash].js',
Run Code Online (Sandbox Code Playgroud)
当我构建时,我可以看到它正确生成了源文件,但在完成ionic build失败后不久,出现一条消息说找不到build/main.js. 这是原始文件名,所以我认为我需要以某种方式让 ionic 知道我正在更改名称main.js 文件。
错误:
[11:00:32] build prod failed: ENOENT: no such file or directory, open
'/Users/work/client/www/build/main.js'
[11:00:32] ionic-app-script task: "build"
[11:00:32] Error: ENOENT: no such file or directory, open '/Users/work/client/www/build/main.js'
我不知道如何更新,ionic build以便它知道寻找动态生成的 main.js 文件名。
EDIT
Much simpler solution that is much less likely to break when ionic has manjor updates.
https://gist.github.com/haydenbr/7df417a8678efc404c820c61b6ffdd24
So cache busting with ionic. It's a hackish solution but it works for now. The problem is ionic build system abstracts a little too much at times. Back in October, it was asked if there was a way to implement cache busting. The ionic team responded that they might consider it in the future, but there hasn't been any activity on it since. Here's the github issue.
So I'll show all the changes to webpack config and package.json and then explain everything.
The config section of your package.json should look like this.
"config": {
"ionic_webpack": "./webpack.config.js",
"ionic_source_map_type": "source-map",
"ionic_uglifyjs": "./www/uglifyjs.config.json"
}
Run Code Online (Sandbox Code Playgroud)
For your webpack config, your entry and output can remain the same. Make sure you have required the following modules and then you'll want to add the following plugins:
var path = require('path'),
fs = require('fs'),
ManifestPlugin = require('webpack-manifest-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin');
Run Code Online (Sandbox Code Playgroud)
...
plugins: [
new HtmlWebpackPlugin({
filename: './../index.html',
inject: 'body',
template: './src/index.html',
title: 'My App',
}),
new ManifestPlugin(),
updateFileName
]
Run Code Online (Sandbox Code Playgroud)
where updateFileName is as follows
function updateFileName() {
this.plugin("done", function() {
var manifest = require(process.env.IONIC_BUILD_DIR + '/manifest.json'),
fileName = process.env.IONIC_OUTPUT_JS_FILE_NAME;
updateUglifyConfig(fileName, manifest);
process.env.IONIC_OUTPUT_JS_FILE_NAME = manifest[fileName];
});
}
function updateUglifyConfig(fileName, manifest) {
var uglifyConfig = {
sourceFile: manifest[fileName],
destFileName: manifest[fileName],
inSourceMap: manifest[fileName + '.map'],
outSourceMap: manifest[fileName + '.map'],
mangle: true,
compress: true,
comments: true
};
// we're writing this to www because it's specific to the current
// build and we don't want to commit it
fs.writeFileSync(
path.join(__dirname, 'www', 'uglifyjs.config.json'),
JSON.stringify(uglifyConfig, null, 4)
);
}
Run Code Online (Sandbox Code Playgroud)
So what's actually happening here? Fist off, in the package.json, we are going to have to generate a new uglify config for the ionic build process. You can change the file name in the middle of the build and as long as you assign the new name to process.env.IONIC_OUTPUT_JS_FILE_NAME then the rest of the build will work fine, except the uglify step will still look for the default name, main.js. We'll see how we generate that below.
Now for the three pluggins we're adding.
The first one does some magic. It's really configurable. How it's set up, it takes a default index.html, sets the title, injects a <script> tag for the javascript output, and then write's it to where you've specified in the filename property. If you're using the default index.html that comes from an ionic starter app, then all you need to do is get rid of the <script src="build/main.js"></script> and it'll automagically put the new link in their for the filename with the hash in it. Docs here.
The next plugin outputs a manifest file for us so that we can know what the filename is with the hash. By default, it outputs it in www/build/. Docs here.
The next plugin is what assigns the new file name to process.env.IONIC_OUTPUT_JS_FILE_NAME and generates the new uglify config for us. Pretty much we grab the manifest that was output, write a new uglify config to the www directory, and then assign the new file name from what we got out of the manifest.
So pretty much that's it. If you don't want the cache busting for dev, keep the html pluggin, get rid of the other two, and then change the output filename back to process.env.IONIC_OUTPUT_JS_FILE_NAME. If you do this, you wont need to reference the main js file in your src/index.html at all. It'll get put in whether your running dev or prod. For more info on using different webpack settups for different environments, check this out.
UPDATE:
For ionic 3:
compilerOptions of your tsconfig:"module": "es2015", "target": "es5"
npm i cheerio --save-devvar cheerio = require('cheerio')Change updateFileName to the following:
function updateFileName() {
this.plugin("done", function(stats) {
var buildOutput = stats.toJson()['assetsByChunkName']['main'],
fileName = process.env.IONIC_OUTPUT_JS_FILE_NAME,
manifest = {
[fileName]: buildOutput[0],
[fileName + '.map']: buildOutput[1]
};
updateUglifyConfig(fileName, manifest);
process.env.IONIC_OUTPUT_JS_FILE_NAME = manifest[fileName];
console.log('IONIC_OUTPUT_JS_FILE_NAME', process.env.IONIC_OUTPUT_JS_FILE_NAME);
});
}
Run Code Online (Sandbox Code Playgroud)Get rid of the Html Webpack Plugin
将以下函数放入 webpack 配置的插件数组中,代替 html 插件:
function updateIndexHTML() {
this.plugin("done", function(stats) {
var buildOutput = stats.toJson()['assetsByChunkName']['main'],
outputFileName = buildOutput[0],
currentIndexHTML = fs.readFileSync(
path.join(__dirname, 'src', 'index.html'),
{ encoding: 'utf8' }
),
$ = cheerio.load(currentIndexHTML);
$('body').append(`<script src="build/${outputFileName}"></script>`);
fs.writeFileSync(
path.join(process.env.IONIC_WWW_DIR, 'index.html'),
$.html()
);
});
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
4818 次 |
| 最近记录: |