Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
4a33813b
Unverified
Commit
4a33813b
authored
May 19, 2021
by
Balvinder Singh Gambhir
Committed by
GitHub
May 19, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] added base-href command in web (#80519)
parent
447b7f1d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
97 additions
and
4 deletions
+97
-4
web.dart
packages/flutter_tools/lib/src/build_system/targets/web.dart
+14
-1
build_web.dart
packages/flutter_tools/lib/src/commands/build_web.dart
+24
-0
devfs_web.dart
packages/flutter_tools/lib/src/isolated/devfs_web.dart
+8
-2
resident_web_runner.dart
...s/flutter_tools/lib/src/isolated/resident_web_runner.dart
+2
-0
compile.dart
packages/flutter_tools/lib/src/web/compile.dart
+2
-0
index.html.tmpl
packages/flutter_tools/templates/app/web/index.html.tmpl
+4
-1
build_web_test.dart
...er_tools/test/commands.shard/hermetic/build_web_test.dart
+2
-0
web_test.dart
...ols/test/general.shard/build_system/targets/web_test.dart
+27
-0
devfs_web_test.dart
.../flutter_tools/test/general.shard/web/devfs_web_test.dart
+14
-0
No files found.
packages/flutter_tools/lib/src/build_system/targets/web.dart
View file @
4a33813b
...
...
@@ -35,6 +35,12 @@ const String kDart2jsOptimization = 'Dart2jsOptimization';
/// Whether to disable dynamic generation code to satisfy csp policies.
const
String
kCspMode
=
'cspMode'
;
/// Base href to set in index.html in flutter build command
const
String
kBaseHref
=
'baseHref'
;
/// Placeholder for base href
const
String
kBaseHrefPlaceholder
=
r'$FLUTTER_BASE_HREF'
;
/// The caching strategy to use for service worker generation.
const
String
kServiceWorkerStrategy
=
'ServiceWorkerStrategy'
;
...
...
@@ -356,7 +362,7 @@ class WebReleaseBundle extends Target {
// in question.
if
(
environment
.
fileSystem
.
path
.
basename
(
inputFile
.
path
)
==
'index.html'
)
{
final
String
randomHash
=
Random
().
nextInt
(
4294967296
).
toString
();
final
String
resultString
=
inputFile
.
readAsStringSync
()
String
resultString
=
inputFile
.
readAsStringSync
()
.
replaceFirst
(
'var serviceWorkerVersion = null'
,
"var serviceWorkerVersion = '
$randomHash
'"
,
...
...
@@ -367,6 +373,13 @@ class WebReleaseBundle extends Target {
"navigator.serviceWorker.register('flutter_service_worker.js')"
,
"navigator.serviceWorker.register('flutter_service_worker.js?v=
$randomHash
')"
,
);
if
(
resultString
.
contains
(
kBaseHrefPlaceholder
)
&&
environment
.
defines
[
kBaseHref
]
==
null
)
{
resultString
=
resultString
.
replaceAll
(
kBaseHrefPlaceholder
,
'/'
);
}
else
if
(
resultString
.
contains
(
kBaseHrefPlaceholder
)
&&
environment
.
defines
[
kBaseHref
]
!=
null
)
{
resultString
=
resultString
.
replaceAll
(
kBaseHrefPlaceholder
,
environment
.
defines
[
kBaseHref
]);
}
outputFile
.
writeAsStringSync
(
resultString
);
continue
;
}
...
...
packages/flutter_tools/lib/src/commands/build_web.dart
View file @
4a33813b
...
...
@@ -10,6 +10,7 @@ import '../base/common.dart';
import
'../build_info.dart'
;
import
'../build_system/targets/web.dart'
;
import
'../features.dart'
;
import
'../globals.dart'
as
globals
;
import
'../project.dart'
;
import
'../runner/flutter_command.dart'
show
DevelopmentArtifact
,
FlutterCommandResult
;
...
...
@@ -42,6 +43,7 @@ class BuildWebCommand extends BuildSubCommand {
'to view and debug the original source code of a compiled and minified Dart '
'application.'
);
argParser
.
addOption
(
'pwa-strategy'
,
defaultsTo:
kOfflineFirst
,
help:
'The caching strategy to be used by the PWA service worker.'
,
...
...
@@ -59,6 +61,13 @@ class BuildWebCommand extends BuildSubCommand {
'is not desirable'
,
},
);
argParser
.
addOption
(
'base-href'
,
help:
'Overrides the href attribute of the <base> tag in web/index.html. '
'No change is done to web/index.html file if this flag is not provided. '
'The value has to start and end with a slash "/". '
'For more information: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base'
);
}
@override
...
...
@@ -87,6 +96,20 @@ class BuildWebCommand extends BuildSubCommand {
if
(
buildInfo
.
isDebug
)
{
throwToolExit
(
'debug builds cannot be built directly for the web. Try using "flutter run"'
);
}
if
(
stringArg
(
'base-href'
)
!=
null
&&
!(
stringArg
(
'base-href'
).
startsWith
(
'/'
)
&&
stringArg
(
'base-href'
).
endsWith
(
'/'
)))
{
throwToolExit
(
'base-href should start and end with /'
);
}
if
(!
globals
.
fs
.
currentDirectory
.
childDirectory
(
'web'
)
.
childFile
(
'index.html'
)
.
readAsStringSync
()
.
contains
(
kBaseHrefPlaceholder
)
&&
stringArg
(
'base-href'
)
!=
null
)
{
throwToolExit
(
"Couldn't find the placeholder for base href. "
r'Please add `<base href="$FLUTTER_BASE_HREF">` to web/index.html'
);
}
displayNullSafetyMode
(
buildInfo
);
await
buildWeb
(
flutterProject
,
...
...
@@ -96,6 +119,7 @@ class BuildWebCommand extends BuildSubCommand {
stringArg
(
'pwa-strategy'
),
boolArg
(
'source-maps'
),
boolArg
(
'native-null-assertions'
),
stringArg
(
'base-href'
),
);
return
FlutterCommandResult
.
success
();
}
...
...
packages/flutter_tools/lib/src/isolated/devfs_web.dart
View file @
4a33813b
...
...
@@ -28,6 +28,7 @@ import '../base/logger.dart';
import
'../base/net.dart'
;
import
'../base/platform.dart'
;
import
'../build_info.dart'
;
import
'../build_system/targets/web.dart'
;
import
'../bundle.dart'
;
import
'../cache.dart'
;
import
'../compile.dart'
;
...
...
@@ -488,6 +489,12 @@ class WebAssetServer implements AssetReader {
.
childFile
(
'index.html'
);
if
(
indexFile
.
existsSync
())
{
String
indexFileContent
=
indexFile
.
readAsStringSync
();
if
(
indexFileContent
.
contains
(
kBaseHrefPlaceholder
))
{
indexFileContent
=
indexFileContent
.
replaceAll
(
kBaseHrefPlaceholder
,
'/'
);
headers
[
HttpHeaders
.
contentLengthHeader
]
=
indexFileContent
.
length
.
toString
();
return
shelf
.
Response
.
ok
(
indexFileContent
,
headers:
headers
);
}
headers
[
HttpHeaders
.
contentLengthHeader
]
=
indexFile
.
lengthSync
().
toString
();
return
shelf
.
Response
.
ok
(
indexFile
.
openRead
(),
headers:
headers
);
...
...
@@ -1025,13 +1032,12 @@ String _stripTrailingSlashes(String path) {
String
_parseBasePathFromIndexHtml
(
File
indexHtml
)
{
final
String
htmlContent
=
indexHtml
.
existsSync
()
?
indexHtml
.
readAsStringSync
()
:
_kDefaultIndex
;
final
Document
document
=
parse
(
htmlContent
);
final
Element
baseElement
=
document
.
querySelector
(
'base'
);
String
baseHref
=
baseElement
?.
attributes
==
null
?
null
:
baseElement
.
attributes
[
'href'
];
if
(
baseHref
==
null
)
{
if
(
baseHref
==
null
||
baseHref
==
kBaseHrefPlaceholder
)
{
baseHref
=
''
;
}
else
if
(!
baseHref
.
startsWith
(
'/'
))
{
throw
ToolExit
(
...
...
packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
View file @
4a33813b
...
...
@@ -297,6 +297,7 @@ class ResidentWebRunner extends ResidentRunner {
kNoneWorker
,
true
,
debuggingOptions
.
nativeNullAssertions
,
null
,
);
}
await
device
.
device
.
startApp
(
...
...
@@ -365,6 +366,7 @@ class ResidentWebRunner extends ResidentRunner {
kNoneWorker
,
true
,
debuggingOptions
.
nativeNullAssertions
,
kBaseHref
,
);
}
on
ToolExit
{
return
OperationResult
(
1
,
'Failed to recompile application.'
);
...
...
packages/flutter_tools/lib/src/web/compile.dart
View file @
4a33813b
...
...
@@ -26,6 +26,7 @@ Future<void> buildWeb(
String
serviceWorkerStrategy
,
bool
sourceMaps
,
bool
nativeNullAssertions
,
String
baseHref
,
)
async
{
if
(!
flutterProject
.
web
.
existsSync
())
{
throwToolExit
(
'Missing index.html.'
);
...
...
@@ -49,6 +50,7 @@ Future<void> buildWeb(
kTargetFile:
target
,
kHasWebPlugins:
hasWebPlugins
.
toString
(),
kCspMode:
csp
.
toString
(),
kBaseHref
:
baseHref
,
kSourceMapsEnabled:
sourceMaps
.
toString
(),
kNativeNullAssertions:
nativeNullAssertions
.
toString
(),
if
(
serviceWorkerStrategy
!=
null
)
...
...
packages/flutter_tools/templates/app/web/index.html.tmpl
View file @
4a33813b
...
...
@@ -10,8 +10,11 @@
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base
href=
"
/
"
>
<base
href=
"
$FLUTTER_BASE_HREF
"
>
<meta
charset=
"UTF-8"
>
<meta
content=
"IE=Edge"
http-equiv=
"X-UA-Compatible"
>
...
...
packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart
View file @
4a33813b
...
...
@@ -60,6 +60,7 @@ void main() {
null
,
true
,
true
,
null
,
),
throwsToolExit
());
},
overrides:
<
Type
,
Generator
>{
Platform:
()
=>
fakePlatform
,
...
...
@@ -119,6 +120,7 @@ void main() {
'DartObfuscation'
:
'false'
,
'TrackWidgetCreation'
:
'false'
,
'TreeShakeIcons'
:
'false'
,
'baseHref'
:
null
,
});
}),
});
...
...
packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
View file @
4a33813b
...
...
@@ -101,6 +101,33 @@ void main() {
expect
(
environment
.
outputDir
.
childFile
(
'version.json'
),
exists
);
}));
test
(
'Base href is created in index.html with given base-href after release build'
,
()
=>
testbed
.
run
(()
async
{
environment
.
defines
[
kBuildMode
]
=
'release'
;
environment
.
defines
[
kBaseHref
]
=
'/basehreftest/'
;
final
Directory
webResources
=
environment
.
projectDir
.
childDirectory
(
'web'
);
webResources
.
childFile
(
'index.html'
).
createSync
(
recursive:
true
);
webResources
.
childFile
(
'index.html'
).
writeAsStringSync
(
'''
<!DOCTYPE html><html><base href="
$kBaseHrefPlaceholder
"><head></head></html>
'''
);
environment
.
buildDir
.
childFile
(
'main.dart.js'
).
createSync
();
await
const
WebReleaseBundle
().
build
(
environment
);
expect
(
environment
.
outputDir
.
childFile
(
'index.html'
).
readAsStringSync
(),
contains
(
'/basehreftest/'
));
}));
test
(
'null base href does not override existing base href in index.html'
,
()
=>
testbed
.
run
(()
async
{
environment
.
defines
[
kBuildMode
]
=
'release'
;
final
Directory
webResources
=
environment
.
projectDir
.
childDirectory
(
'web'
);
webResources
.
childFile
(
'index.html'
).
createSync
(
recursive:
true
);
webResources
.
childFile
(
'index.html'
).
writeAsStringSync
(
'''
<!DOCTYPE html><html><head><base href='
/
basehreftest
/
'></head></html>
'''
);
environment
.
buildDir
.
childFile
(
'main.dart.js'
).
createSync
();
await
const
WebReleaseBundle
().
build
(
environment
);
expect
(
environment
.
outputDir
.
childFile
(
'index.html'
).
readAsStringSync
(),
contains
(
'/basehreftest/'
));
}));
test
(
'WebReleaseBundle copies dart2js output and resource files to output directory'
,
()
=>
testbed
.
run
(()
async
{
environment
.
defines
[
kBuildMode
]
=
'release'
;
final
Directory
webResources
=
environment
.
projectDir
.
childDirectory
(
'web'
);
...
...
packages/flutter_tools/test/general.shard/web/devfs_web_test.dart
View file @
4a33813b
...
...
@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/artifacts.dart';
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/platform.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_system/targets/web.dart'
;
import
'package:flutter_tools/src/compile.dart'
;
import
'package:flutter_tools/src/convert.dart'
;
import
'package:flutter_tools/src/globals.dart'
as
globals
;
...
...
@@ -209,6 +210,19 @@ void main() {
expect
(
await
response
.
readAsString
(),
htmlContent
);
}));
test
(
'serves index.html at / if href attribute is
$kBaseHrefPlaceholder
'
,
()
=>
testbed
.
run
(()
async
{
const
String
htmlContent
=
'<html><head><base href ="
$kBaseHrefPlaceholder
"></head><body id="test"></body></html>'
;
final
Directory
webDir
=
globals
.
fs
.
currentDirectory
.
childDirectory
(
'web'
)
..
createSync
();
webDir
.
childFile
(
'index.html'
).
writeAsStringSync
(
htmlContent
);
final
Response
response
=
await
webAssetServer
.
handleRequest
(
Request
(
'GET'
,
Uri
.
parse
(
'http://foobar/'
)));
expect
(
response
.
statusCode
,
HttpStatus
.
ok
);
expect
(
await
response
.
readAsString
(),
htmlContent
.
replaceAll
(
kBaseHrefPlaceholder
,
'/'
));
}));
test
(
'does not serve outside the base path'
,
()
=>
testbed
.
run
(()
async
{
webAssetServer
.
basePath
=
'base/path'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment