-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Decouple XModule styles from LMS/Studio styles #32018
Decouple XModule styles from LMS/Studio styles #32018
Conversation
Thanks for the pull request, @andrey-canon! Please note that it may take us up to several weeks or months to complete a review and merge your PR. Feel free to add as much of the following information to the ticket as you can:
All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here. Please let us know once your PR is ready for our review and all tests are green. |
@andrey-canon Looks like there are a couple of check failures, can you have a look? |
ae3656e
to
ce0f9cb
Compare
Hi @kdmccormick, @e0d, this is ready for review |
ce0f9cb
to
430cc03
Compare
Sorry @andrey-canon , Axim got together in-person last week and I was not able to do any code review. I have not forgotten about this. |
430cc03
to
520847f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is excellent. I am still testing it locally, but here are the only issues I found with the code itself.
Once this merges and the styles are decoupled, what do you think the next step should be?
xmodule/util/xmodule_django.py
Outdated
from webpack_loader.loader import WebpackLoader | ||
|
||
|
||
class XmoduleWebpackLoader(WebpackLoader): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's standard to capitalize the "M": XModuleWebpackLoader
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed
xmodule/util/xmodule_django.py
Outdated
|
||
|
||
class XmoduleWebpackLoader(WebpackLoader): | ||
"""Custom webpack loader.This is where behavior can be customized |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For docstrings, our Python style guide recommends breaking the line after the opening """
:
"""Custom webpack loader.This is where behavior can be customized | |
""" | |
Custom webpack loader.This is where behavior can be customized |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
xmodule/util/xmodule_django.py
Outdated
|
||
class XmoduleWebpackLoader(WebpackLoader): | ||
"""Custom webpack loader.This is where behavior can be customized | ||
as to how edx-platform static files are loaded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you be more specific in this docstring? It is not just any old edx-platform static files which you handle here: it is specifically assets for XModule-style XBlocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check last commit, also I improved the docstring for load_assets method
@andrey-canon your test instructions mention:
This is unnecessary, as your PR already makes this change, right? |
@kdmccormick yes, you are right that's unnecessary I added that because when I was developing I had to and I just copied some notes in the testing instructions |
@andrey-canon I tested this and couldn't find any issues, nice work! If you rebase & apply the requested changes, then I should be able to merge this within the next couple of days. |
520847f
to
0d0e441
Compare
@kdmccormick Great, just let me know to squash the commits |
@kdmccormick, IMO this requires a style refactor, personally I don't like these module_styles_lines and descriptor module_styles_lines it'd be great if both of them depend on just one standard import or the same list of imports. In a bigger picture I don't have the answer right know, probably the next step should be identify and decouple more assets in order to do the loading process lighter or something more complex like try to migrate some xblocks to react applications since there are more independent from other assets. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just one suggestion. Go ahead and squash, and I'll look into when I can safely merge this.
|
||
def load_assets(self): | ||
""" | ||
This function will append XModule css files to the standard load_assets results. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really helpful docstring, thank you!
xmodule/static_content.py
Outdated
module_styles_lines = [ | ||
"@import 'bourbon/bourbon';", | ||
"@import 'vendor/bi-app/bi-app-ltr';", | ||
"@import 'lms/theme/variables';", | ||
"@import 'cms/theme/variables-v1';", | ||
"@import 'mixins';", | ||
"@import 'mixins-inherited';", | ||
] | ||
|
||
return _write_styles( | ||
'.xmodule_edit', | ||
output_root, XBLOCK_CLASSES, | ||
'get_studio_view_css', | ||
module_styles_lines, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
module_styles_lines = [ | |
"@import 'bourbon/bourbon';", | |
"@import 'vendor/bi-app/bi-app-ltr';", | |
"@import 'lms/theme/variables';", | |
"@import 'cms/theme/variables-v1';", | |
"@import 'mixins';", | |
"@import 'mixins-inherited';", | |
] | |
return _write_styles( | |
'.xmodule_edit', | |
output_root, XBLOCK_CLASSES, | |
'get_studio_view_css', | |
module_styles_lines, | |
descriptor_styles_lines = [ | |
"@import 'bourbon/bourbon';", | |
"@import 'vendor/bi-app/bi-app-ltr';", | |
"@import 'lms/theme/variables';", | |
"@import 'cms/theme/variables-v1';", | |
"@import 'mixins';", | |
"@import 'mixins-inherited';", | |
] | |
return _write_styles( | |
'.xmodule_edit', | |
output_root, XBLOCK_CLASSES, | |
'get_studio_view_css', | |
descriptor_styles_lines, |
(I had left a comment about next steps, but I moved it over to the issue since it's beyond this PR: #31624 (comment)) |
@andrey-canon I was wrong, due to some vacations at 2U and some large XModule refactorings that are in line to be merged first, we'll have to wait in order to merge this with proper 2U on-call support. I'll merge it late April or early May. In the meantime, it looks like there is a JS test failure. Just ping me if you need approval for the tests to run at any point. |
0d0e441
to
b4c47f0
Compare
Hi @kdmccormick, I have already applied the suggestion and I made the squash :) |
Thanks @andrey-canon ! Would you mind adding some details to the body of the commit message as well as a link to the issue? |
ok, I think at that time we will need a branch rebase, but no problem just let me know when to do that Regarding the JS test I think we are facing a flaky test since I had the same failure three days ago and the solution was the same as today, make a rebase. |
b4c47f0
to
8c772bc
Compare
Done |
8c772bc
to
d3f82fa
Compare
Code looks great. I'm just testing this locally one last time. BTW, I re-named the PR so it'll be easier for folks who aren't on this project to understand. |
@kdmccormick have you confirmed this change fully supports the existing requirements for global CSS of a course? If so, then this is able to be merged at your convenience. Thanks! |
Good call out @jristau1984 , I'm testing that now. |
@jristau1984 I was able to confirm that course-wide styling still works. Here was my test process:
I'll merge this ~8AM EST tomorrow. |
@andrey-canon 🎉 Your pull request was merged! Please take a moment to answer a two question survey so we can improve your experience in the future. |
This reverts commit 471ba91.
This is being reverted in #32183, as red-theme compilation failed when building for deployment to edx.org. |
EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production. |
EdX Release Notice: This PR has been deployed to the production environment. |
Will re-merge in: #32188 |
This basically changes how the xmodule static files are generated and consumed in order to separate the Xblock styles from general style files. Includes: * build: decople XModule style assets by using a custom webpack loader * build: move scss imports to its specific file * build: fix: add system dirs to theme lookup paths. This is an amendment to #32018 Addressing the issue #31624
This basically changes how the xmodule static files are generated and consumed in order to separate the Xblock styles from general style files. Includes: * build: decople XModule style assets by using a custom webpack loader * build: move scss imports to its specific file * build: fix: add system dirs to theme lookup paths. (fixes attempt 1) * build: fix: use bootstrap variables instead of lms variables (fixes attempt 2) This is an amendment to #32188, which itself was an amendment to #32018. Addressing the issue #31624
In ~Palm and earlier, all built-in XBlock Sass was included into LMS and CMS styles before being compiled. The generated CSS was coupled together with broader LMS/CMS CSS. This means that comprehensive themes have been able to modify built-in XBlock appearance by setting certain Sass variables. We say that built-in XBlock Sass was, and is expected to be, "theme-aware". Shortly after Palm, we decoupled XBlock Sass from LMS and CMS Sass [1]. Each built-in block's Sass is now compiled into two separate CSS targets, one for block editing and one for block display. The CSS, now located at `common/static/css/xmodule`, is injected into the running Webpack context with the new `XModuleWebpackLoader`. Built-in XBlocks already used `add_webpack_to_fragment` in order to add JS Webpack bundles to their view fragments, so when CSS was added to Webpack, it Just Worked. This unlocked a slieu of simplifications for static asset processing [2]; however, it accidentally made XBlock Sass theme-*unaware*, or perhaps theme-confused, since the CSS was targeted at `common/static/css/xmodule` regardless of the theme. The result of this is that **built-in XBlock views will use CSS based on the Sass variables _last theme to be compiled._** Sass variables are only used in a handful of places in XBlocks, so the bug is subtle, but it is there for those running off of master. For example, using edX.org's theme on master, we can see that there is a default blue underline in the Studio sequence nav [3]. With this bugfix, it becomes the standard edX.org greenish-black [4]. This commit makes several changes, firstly to fix the bug, and secondly to leave ourselves with a more comprehensible asset setup in the `xmodule/` directory. * We remove the `XModuleWebpackLoader`, thus taking built-in XBlock Sass back out of Webpack. * We compile XBlock Sass not to `common/static/css/xmodule`, but to: * `[lms|cms]/static/css` for the default theme, and * `<THEME_ROOT>/[lms|cms]/static/css`, for any custom theme. This is where the comprehensive theming system expects to find themable assets. Unfortunately, this does mean that the Sass is compiled twice, both for LMS and CMS. We would have liked to compile it once to somewhere in the `common/`, but comprehensive theming does not consider `common/` assets to be themable. * We split `add_webpack_to_fragment` into two more specialized functions: * `add_webpack_js_to_fragment` , for adding *just* JS from a Webpack bundle, and * `add_sass_to_fragment`, for adding static links to CSS compiled themable Sass (not Webpack). Both these functions are moved to a new module `xmodule/util/builtin_assets.py`, since the original module (`xmodule/util/xmodule_django.py`) didn't make a ton of sense. * In an orthogonal bugfix, we merge Sass `CourseInfoBlock`, `StaticTabBlock`, `AboutBlock` into the `HtmlBlock` Sass files. The first three were never used, as their styling was handled by `HtmlBlock` (their shared parent class). * As a refactoring, we change Webpack bundle names and Sass module names to be less misleading: * student_view, public_view, and author_view: was `<Name>BlockPreview`, is now `<Name>BlockDisplay`. * studio_view: was `<Name>BlockStudio`, is now `<Name>BlockEditor`. * As a refactoring, we move the contents of `xmodule/static` into the existing `xmodule/assets` directory, and adopt its simper structure. We now have: * `xmodule/assets/*.scss`: Top-level compiled Sass modules. These could be collapsed away in a future refactoring. * `xmodule/assets/<blocktype>/*`: Resources for each block, including both JS modules and Sass includes (underscore-prefixed so that they aren't compiled). This structure maps closely with what externally-defined XBlocks do. * `xmodule/js` still exists, but it will soon be folded into the `xmodule/assets`. * We add a new README [4] to explain the new structure, and also update a docstring in `openedx/lib/xblock/utils` which had fallen out of date with reality. * Side note: We avoid the term "XModule" in all of this, because that's (thankfully) become a much less useful/accurate way to describe these blocks. Instead, we say "built-in XBlocks". Refs: 1. openedx#32018 2. openedx#32292 3. https://github.com/openedx/edx-platform/assets/3628148/8b44545d-0f71-4357-9385-69d6e1cca86f 4. https://github.com/openedx/edx-platform/assets/3628148/d0b7b309-b8a4-4697-920a-8a520e903e06 5. https://github.com/openedx/edx-platform/tree/master/xmodule/assets#readme Part of: openedx#32292
In ~Palm and earlier, all built-in XBlock Sass was included into LMS and CMS styles before being compiled. The generated CSS was coupled together with broader LMS/CMS CSS. This means that comprehensive themes have been able to modify built-in XBlock appearance by setting certain Sass variables. We say that built-in XBlock Sass was, and is expected to be, "theme-aware". Shortly after Palm, we decoupled XBlock Sass from LMS and CMS Sass [1]. Each built-in block's Sass is now compiled into two separate CSS targets, one for block editing and one for block display. The CSS, now located at `common/static/css/xmodule`, is injected into the running Webpack context with the new `XModuleWebpackLoader`. Built-in XBlocks already used `add_webpack_to_fragment` in order to add JS Webpack bundles to their view fragments, so when CSS was added to Webpack, it Just Worked. This unlocked a slieu of simplifications for static asset processing [2]; however, it accidentally made XBlock Sass theme-*unaware*, or perhaps theme-confused, since the CSS was targeted at `common/static/css/xmodule` regardless of the theme. The result of this is that **built-in XBlock views will use CSS based on the Sass variables _last theme to be compiled._** Sass variables are only used in a handful of places in XBlocks, so the bug is subtle, but it is there for those running off of master. For example, using edX.org's theme on master, we can see that there is a default blue underline in the Studio sequence nav [3]. With this bugfix, it becomes the standard edX.org greenish-black [4]. This commit makes several changes, firstly to fix the bug, and secondly to leave ourselves with a more comprehensible asset setup in the `xmodule/` directory. * We remove the `XModuleWebpackLoader`, thus taking built-in XBlock Sass back out of Webpack. * We compile XBlock Sass not to `common/static/css/xmodule`, but to: * `[lms|cms]/static/css` for the default theme, and * `<THEME_ROOT>/[lms|cms]/static/css`, for any custom theme. This is where the comprehensive theming system expects to find themable assets. Unfortunately, this does mean that the Sass is compiled twice, both for LMS and CMS. We would have liked to compile it once to somewhere in the `common/`, but comprehensive theming does not consider `common/` assets to be themable. * We split `add_webpack_to_fragment` into two more specialized functions: * `add_webpack_js_to_fragment` , for adding *just* JS from a Webpack bundle, and * `add_sass_to_fragment`, for adding static links to CSS compiled themable Sass (not Webpack). Both these functions are moved to a new module `xmodule/util/builtin_assets.py`, since the original module (`xmodule/util/xmodule_django.py`) didn't make a ton of sense. * In an orthogonal bugfix, we merge Sass `CourseInfoBlock`, `StaticTabBlock`, `AboutBlock` into the `HtmlBlock` Sass files. The first three were never used, as their styling was handled by `HtmlBlock` (their shared parent class). * As a refactoring, we change Webpack bundle names and Sass module names to be less misleading: * student_view, public_view, and author_view: was `<Name>BlockPreview`, is now `<Name>BlockDisplay`. * studio_view: was `<Name>BlockStudio`, is now `<Name>BlockEditor`. * As a refactoring, we move the contents of `xmodule/static` into the existing `xmodule/assets` directory, and adopt its simper structure. We now have: * `xmodule/assets/*.scss`: Top-level compiled Sass modules. These could be collapsed away in a future refactoring. * `xmodule/assets/<blocktype>/*`: Resources for each block, including both JS modules and Sass includes (underscore-prefixed so that they aren't compiled). This structure maps closely with what externally-defined XBlocks do. * `xmodule/js` still exists, but it will soon be folded into the `xmodule/assets`. * We add a new README [4] to explain the new structure, and also update a docstring in `openedx/lib/xblock/utils` which had fallen out of date with reality. * Side note: We avoid the term "XModule" in all of this, because that's (thankfully) become a much less useful/accurate way to describe these blocks. Instead, we say "built-in XBlocks". Refs: 1. #32018 2. #32292 3. https://github.com/openedx/edx-platform/assets/3628148/8b44545d-0f71-4357-9385-69d6e1cca86f 4. https://github.com/openedx/edx-platform/assets/3628148/d0b7b309-b8a4-4697-920a-8a520e903e06 5. https://github.com/openedx/edx-platform/tree/master/xmodule/assets#readme Part of: #32292
`module-js` and `module-descriptor-js` are old JavaScript group indicators, left over from when we managed XModule assets via Django Pipeline. We would like to get rid of them in order to make it easier to build XModule JS without using Python. There is one single usage of `module-js` in the entire platform (the rest have been replaced with Webpack references, which is the less-outdated way of managing XModule assets :). The lone `module-js` reference was added in 2013 [1] so that circuit diagrams would display in the course wiki. However, the ability to render circuits in the wiki was removed in 2015 [2], so it is safe to remove the reference. There is also one single usage of `module-descriptor-js`. It's in the legacy bulk email editor, which hackily cribs from the old HtmlBlock editor. Fortunately, we are able to simply replace the Django Pipeline reference with the equivalent XModule JS Webpack bundle. (Note: The old email editor is currently still supported, but is currently being replaced by frontend-app-communications, so this hack will be gone eventually). Finally, this commit also sneaks in one styling fix: it adds the HtmlBlockEditor CSS back to the aforementioned legacy bulk email page. The missing CSS was causing a read-only 1-line codemirror editor to appear below the HTML editor [3]. This bug was introduced during the original XModule SCSS decoupling [4], which removed builtin block CSS from the LMS-wide bundle, thus removing the HTML editor CSS from the bulk email page. We imagine that nobody noticed because the bug only exists in master (not Palm) and frontend-app-communications seems to be globally enabled on edx.org. As a simple fix, we add the new CSS link to the legacy bulk email page, and it renders fine again [5]. References: 1. openedx@3fc59b3 2. openedx#10324 3. Before fix: https://github.com/openedx/edx-platform/assets/3628148/25fc41b2-403d-4339-8c49-0b04664dfa02 4. openedx#32018 5. After fix: https://github.com/openedx/edx-platform/assets/3628148/9a5d74f1-cc83-4ebe-8f0c-ee270f7721b8 Part of: openedx#32481
`module-js` and `module-descriptor-js` are old JavaScript group indicators, left over from when we managed XModule assets via Django Pipeline. We would like to get rid of them in order to make it easier to build XModule JS without using Python. There is one single usage of `module-js` in the entire platform (the rest have been replaced with Webpack references, which is the less-outdated way of managing XModule assets :). The lone `module-js` reference was added in 2013 [1] so that circuit diagrams would display in the course wiki. However, the ability to render circuits in the wiki was removed in 2015 [2], so it is safe to remove the reference. There is also one single usage of `module-descriptor-js`. It's in the legacy bulk email editor, which hackily cribs from the old HtmlBlock editor. Fortunately, we are able to simply replace the Django Pipeline reference with the equivalent XModule JS Webpack bundle. (Note: The old email editor is currently still supported, but is currently being replaced by frontend-app-communications, so this hack will be gone eventually). Finally, this commit also sneaks in one styling fix: it adds the HtmlBlockEditor CSS back to the aforementioned legacy bulk email page. The missing CSS was causing a read-only 1-line codemirror editor to appear below the HTML editor [3]. This bug was introduced during the original XModule SCSS decoupling [4], which removed builtin block CSS from the LMS-wide bundle, thus removing the HTML editor CSS from the bulk email page. We imagine that nobody noticed because the bug only exists in master (not Palm) and frontend-app-communications seems to be globally enabled on edx.org. As a simple fix, we add the new CSS link to the legacy bulk email page, and it renders fine again [5]. References: 1. 3fc59b3 2. #10324 3. Before fix: https://github.com/openedx/edx-platform/assets/3628148/25fc41b2-403d-4339-8c49-0b04664dfa02 4. #32018 5. After fix: https://github.com/openedx/edx-platform/assets/3628148/9a5d74f1-cc83-4ebe-8f0c-ee270f7721b8 Part of: #32481
Description
Addressing this issue #31624
This basically changes how the xmodule static files are generated and consumed in order to separate the Xblock styles from general style files.
Generation
Run command
openedx-assets xmodule
Current generation basically takes the
preview_view_css
orstudio_view_css
value from the XBlock class and creates hashed files in/common/static/xmodule/{descriptors or modules}/css
folder then those files are imported in a common file called_module-styles.scss
in the same folderExample of _module-styles.scss
This pr changes that in the following way
_module-styles.scss
is removed and an independent file is created per XblockExample
Compilation
Run command
openedx-assets common
Previously module-styles.scss files were imported in lms and cms scss files, after running the
openedx-assets common
command that generated the lms-course.css and studio-main-v1.css files with the xblocks stylesThis pr changes that in the following way:
common/static/xmodule/{modules or descriptors}/scss
) to the compilation dirs. This will generate a compiled css file for each scss file in those folderscommon/static/css/xmodule/
that's why studio needs access to the lms styles in the previewExample
Consumption
Currently every xblock loads its js by using this function, that functions also allows to load CSS, so this pr adds a custom webpack loader in order to include the CSS files generated previously. XmoduleWebpackLoader will append the CSS files in
common/stactic/css/xmodule
to assets found by the standard webpack loaderResults
Testing instructions
This instruction are just valid in a tutor environment
docker exec -it tutor_nightly_dev-lms-1 /bin/bash
openedx-assets xmodule
and check the generation partopenedx-assets common
and check the compilation partOther information
More details about generation and compilation static files could be found here