Repository: oppia/oppia

Issue:
Integrate /extensions into webpack
We now use webpack for files in `core/templates/dev/head`.

We should extend this usage to the `/extensions` folder.

TODO:
- [ ] ckeditor_plugins

PR CREATED:
- [x] rich_text_components - #6882 
- [x] interactions
- [x] classifiers
- [x] visualizations - #6885 
- [x] objects - @kevinlee12 (#6889)
- [x] value_generators - #6900
- [x] dependencies
Add preload links for Font Awesome fonts
Add `<link rel=preload>` for Font Awesome fonts according to Lighthouse measurement (https://developers.google.com/web/tools/lighthouse/audits/preload?utm_source=lighthouse&utm_medium=devtools).
![image](https://user-images.githubusercontent.com/10142938/62482365-4076c580-b7b5-11e9-8246-b234f645cea0.png)
Probably wait before #7189 gets in since it can simplify things.


Discussion:
How to handle the subfolders of `/extensions`:

**ckeditor_plugins** (NOT needed for Yash):
The one and only `pre` plugin is loaded from `core/templates/dev/head/components/ck-editor-helpers/ck-editor-rte.directive.ts` we just need to find out if we are able to pass the code by webpack.

**classifiers** (needed for Yash):
Classifiers are script-imported in `extensions/dependencies`, after whe handle `extensions/dependencies` we can just `require()` the classifiers.

**dependencies** (needed for Yash):
We define dependencies in an interaction Python file. These dependencies are HTML files containing script-imports.

**interactions** (needed for Yash):
We use HTML that contains script-imports for JS files and also link-imports for CSS files. We use all interactions in creator_dashboard (why?), we use big subset of interactions in exploration_player and exploration_editor and a small subset of interactions in skill_editor, topic_editor, and practice_session.

Create file that contain `require()` for every interaction, create files that `require()` the subsets of interactions.

**objects** (needed for Yash):
For now, objects can just be moved from HTML script-imports to the appropriate `.ts` file connected to that HTML file. So for example `<script src="/extensions/objects/templates/GraphEditorDirective.js"></script>` in `exploration_editor.html` would transofrm to `require('objects/templates/GraphEditorDirective.js');` in `ExplorationEditor.ts`. This will need more work later.

**value_generators** (needed for Yash):
Can be handled similarly to rich_text_components (#6882) and visualizations (#6885).
@Jamesjay4199 how is this going?
@vojtechjelinek can I work on it ..
@Dharmesh-Poddar This is currently blocked by #7189, I can ping you when this issue is ready to be worked on. You can look into other issues for now.

Resolving patch:
diff --git a/scripts/build.py b/scripts/build.py
--- a/scripts/build.py
+++ b/scripts/build.py
@@ -93,15 +93,9 @@
 JS_FILENAME_SUFFIXES_NOT_TO_MINIFY = ('.bundle.js',)
 GENERAL_FILENAMES_TO_IGNORE = ('.pyc', '.stylelintrc', '.DS_Store')
 
-# These files are present in both extensions and local_compiled_js/extensions.
-# They are required in local_compiled_js since they contain code used in
-# other ts files and excluding them from compilation will create compile
-# errors due to missing variables. So, the files should be built only from
-# one location instead of both the locations.
 JS_FILEPATHS_NOT_TO_BUILD = (
-    'extensions/interactions/LogicProof/static/js/generatedDefaultData.js',
-    'extensions/interactions/LogicProof/static/js/generatedParser.js',
-    'core/templates/dev/head/expressions/expression-parser.service.js')
+    'core/templates/dev/head/expressions/expression-parser.service.js',
+    'extensions/ckeditor_plugins/pre/plugin.js')
 
 # These filepaths shouldn't be renamed (i.e. the filepath shouldn't contain
 # hash).
@@ -649,8 +643,8 @@ def should_file_be_built(filepath):
         bool. True if filepath should be built, else False.
     """
     if filepath.endswith('.js'):
-        return filepath not in JS_FILEPATHS_NOT_TO_BUILD and not any(
-            filepath.endswith(p) for p in JS_FILENAME_SUFFIXES_TO_IGNORE)
+        return all(
+            not filepath.endswith(p) for p in JS_FILENAME_SUFFIXES_TO_IGNORE)
     elif filepath.endswith('_test.py'):
         return False
     elif filepath.endswith('.ts'):


Test patch:
diff --git a/scripts/build_test.py b/scripts/build_test.py
--- a/scripts/build_test.py
+++ b/scripts/build_test.py
@@ -328,15 +328,6 @@ def test_should_file_be_built(self):
             self.assertFalse(build.should_file_be_built(service_js_filepath))
             self.assertTrue(build.should_file_be_built(spec_js_filepath))
 
-        with self.swap(
-            build, 'JS_FILEPATHS_NOT_TO_BUILD', (
-                'core/expressions/expression-parser.service.js',)):
-            self.assertFalse(
-                build.should_file_be_built(generated_parser_js_filepath))
-            self.assertTrue(
-                build.should_file_be_built(
-                    compiled_generated_parser_js_filepath))
-
     def test_hash_should_be_inserted(self):
         """Test hash_should_be_inserted returns the correct boolean value
         for filepath that should be hashed.