I have a folder structure like this:
.
├── autocomplete
│ ├── core.js
│ ├── search.js
│ └── user.js
├── build.js
├── collapsible_lists.js
├── griffgrabber
│ ├── canvasobject.js
│ ├── cargame.js
│ ├── car.js
│ ├── griffDrawer.js
│ ├── keylistener.js
│ ├── run.js
│ └── victim.js
├── main.js
├── newsfeed.js
├── require.js
├── shortcut.js
└── sidebar.js
3 directories, 20 files
main.js is the startup file. That file requires a couple of the files, but not all of them. The rest of the files are included with
<script>
require(['shortcut'], function(shortcut){
// ...
})
</script>
in some html files.
This is my build.js file so far:
{
baseUrl: ".",
name: "main",
out: "main-built.js",
}
But it only includes the files that are required by main.js. Is it possible to optimize all the javascript files in one run?
(to expand #Ryan Lynch's suggestion):
Use the include option, as per the documentation:
You can always explicitly add modules that are not found via the optimizer's static analysis by using the include option.
(http://requirejs.org/docs/optimization.html)
{
baseUrl: ".", // ?
appDir: ".", // ?
dir: "output/",
modules: [
{
name: "main",
include: [ "shortcut" ]
}
]
}
More detailed example in the excellent example.build.js (I actually find it more useful than the documentation page)
(sorry, had no time to replicate and test properly to make sure the paths values are correct, I'll try that later and update my answer)
Try including a modules array in your options, so:
{
baseUrl: ".",
out: "main-built.js",
modules: [
{
name: "main"
}
]
}
As per the documentation:
In the modules array, specify the module names that you want to
optimize, in the example, "main". "main" will be mapped to
appdirectory/scripts/main.js in your project. The build system will
then trace the dependencies for main.js and inject them into the
appdirectory-build/scripts/main.js file.
Another - less orthodox - way of achieving this would be to add this "shortcut" module as a dependency to any of the "visible" modules that are discovered by r.js scanning (i.e. "main.js"). This way the entire dependency branch starting at "shortcut" would be included in the output.
Related
Using Vue CLI 3 how can I create a project that contains some static html files at the root of the public directory and an SPA inside of an app folder?
I'd like several static html files including an index.html at the root of the project. I want these static HTML files served outside of the SPA for SEO purposes.
Right now, my project structure looks like this:
.
├── README.md
├── babel.config.js
├── package.json
├── public
│ ├── app
│ │ └── index.html
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ └── main.js
├── vue.config.js
└── yarn.lock
I've tried many different combinations of publicPath and indexPath values in my vue.config.js file. None have achieved what I'm hoping for. I'd like yarn serve to serve both the static HTML files and SPA locally for development. More importantly, I'd like the static HTML files and the SPA properly bundled into the dist folder when I run yarn build. I haven't been able to achieve either goal.
With the configuration below, the public/index.html file that's meant to be static and only displaying at / is being served at both http://localhost:8080/ and http://localhost:8080/app/. Interestingly, at http://localhost:8080/app/ the js resources are being injected into the response along with what's meant to be static HTML.
After running yarn build with the config below I'm left with a /dist/app/index.html file that has the static index.html file code with no javascript injected instead of the SPA code with javascript injected. The /dist/index.html file has the static HTML I expect but all the javascript that's meant for the SPA is injected.
// vue.config.js
module.exports = {
publicPath: '/app/',
indexPath: 'index.html'
}
How can I configure this project to support static html files at the project root and an SPA in the app folder?
You can leverage the feature of Vue CLI to build multipage apps and actually have only one page...
// vue.config.js
module.exports = {
pages: {
index: {
// entry for the page
entry: "src/main.js",
// the source template
template: "public/app/index.html",
// output as dist/app/index.html
filename: "app/index.html",
// when using title option,
// template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
title: "App Index Page",
// chunks to include on this page, by default includes
// extracted common chunks and vendor chunks.
chunks: ["chunk-vendors", "chunk-common", "index"]
}
}
};
I'm developing a Firefox/Chrome Addon/Extension with the same codebase by utilizing the WebExtensions API and the web-extensions-browser polyfill (through webpack and RequireJS).
I noticed Firefox requires code to be unobfuscated and unminified when submitting a version, and thus had to install the unminify-webpack-plugin here.
The last hindering issue I have is that since webpack includes all the required files in one file (as it usually does), the functionality for browser.extension.getBackground() here doesn't work, as all my functions in my background.js are added to an anonymous module function.
Any suggestions on how I'd go about solving this?
Edit 1: Here's some more insight
My folder structure is as follows:
plugin/
├── wepback.config.js
├── manifest.json
├── package.json
├── package-lock.json
├── node_modules/
├── *dist/
├── img/
│ ├── icon.png
│ ├── ... etc
├── src/
│ ├── background/
│ │ ├── background.js
│ │ └── background.html
│ └── popup/
│ ├── popup.js
│ └── popup.html
Where my config is as follows:
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
var UnminifiedWebpackPlugin = require('unminified-webpack-plugin');
module.exports = {
entry: {
background: './src/background/background.js',
popup: './src/popup/popup.js'
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name]/[name].min.js"
},
plugins: [
new CopyPlugin([
{ from: './src/background/background.html', to: 'background/background.html'},
{ from: './src/popup/popup.html', to: 'popup/popup.html'},
{ from: './src/popup/popup.css', to: 'popup/popup.css'},
{ from: './manifest.json', to: 'manifest.json'},
{ from: './img', to: 'img/[name].[ext]'},
]),
new UnminifiedWebpackPlugin()
],
};
Edit 2:
Found the following boiler plate which looks promising. This does seem like an issue that, once solved, can just be reused - so I'll try it out soon and move my project over and test.
https://github.com/fstanis/webextensions-webpack-boilerplate
The best way to work around this is using the extension API's message system, with the sendMessage function and onMessage event - or the port system. See chrome's tutorial on message passing for more information.
Alternatively, you can access the window object directly in your background page - for example, with window.foo = 'bar'. Then getBackgroundPage() will work as expected. Directly mutating or accessing variables across contexts is slightly bad practice, and I'm guessing accessing variables through the window object may be as well, but I think it's probably fine as this is what getBackgroundPage() is intended for anyway.
I'm just starting with front-end web developpement(javascript hell with all these package manager/bundler) and I'm trying to use typescript + browsify
so I create a index.ts file and download the uniq module(using npm) just to test ts file compilation
here is my index.ts
/// <reference path="node_modules/uniq/uniq.d.ts" />
import {unique} from "uniq";
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
console.log(unique(data));
uniq.d.ts
// Type definitions for uniq
// Project: https://www.npmjs.com/package/uniq
// Definitions by: Hans Windhoff <https://github.com/hansrwindhoff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
interface Uniq{
<T>(ip:Array<T>): Array<T>;
}
declare var uniq :Uniq;
declare module "uniq" {
export = uniq;
}
directory structure
.
├── entry.ts
├── node_modules
│ └── uniq
│ ├── LICENSE
│ ├── package.json
│ ├── README.md
│ ├── test
│ │ └── test.js
│ ├── uniq.d.ts
│ └── uniq.ts
└── package.json
but when I try to compile the index.ts I got this error :
error TS2688: Cannot find type definition file for 'uniq'.
First
you probably have the path wrong:
/// <reference path="node_modules/uniq/uniq.d.ts" />
Maybe ../../node_modules/uniq/uniq.d.ts. Instead of britle paths like this please use tsconfig.json : https://basarat.gitbooks.io/typescript/content/docs/project/tsconfig.html
Second
Based on the .d.ts you showed your import import {unique} from "uniq"; is also wrong. It should be import unique = require('uniq') since its a single function export. You will get an error about this anyways after you fix first. Enjoy 🌹
My problem lies in the next. I have a javascript application. It utilises the so called module pattern. That is I have multiple js files (one for each class) and during the build process all these files are put to a single file and wrapped in the IIFE. So in my karma config file I specify
files: ['src/**/*.js', 'tests/**/*.js']
The problem arises because I need to use several "modules" in this app. Here is the example of the tree structure of the code:
├── karma_unit.conf.js
├── src
│ ├── Bar
│ │ └── module.js
│ └── Foo
│ └── module.js
└── tests
└── unit
├── Bar
│ └── test.js
└── Foo
└── test.js
So I have two Module classes at the same time. This is not the problem with the "built" code. But for the unit tests this is the problem, because this is the name conflict.
I know that I can have different config files for each such a module and run tests several times (one per a single config file), but this is very undesirable.
Also I supposed that files are executed with respect to their inclusion order, so I tried to write in the config file:
files: [
'src/Foo/*.js',
'tests/Foo/*.js',
'src/Bar/*.js',
'tests/Bar/*.js',
]
But this did not help.
So my question is: how can I circumvent this situation when I'm forced to have several javascript classes with the same name in a single project without running tests several times or renaming these classes?
My appreciation in advance.
This is the reference link that details a solution for your query:
http://karma-runner.github.io/0.8/plus/RequireJS.html
I have the following Javascript folder structure:
- js
- libs
- Backbone
- Underscore
- Require
- Etc
- models
- templates
- views
- app.js
- main.js
- router.js
In order to avoid cluttering the front end router with callback functions, ideally I want to delegate the functionality to external modules and have at maximum 1 line of code per route. This way I keep a very clean overview and I should never actually touch the router again when delegate functionality changes.
For example:
var Router = Backbone.Router.extend({
/* --- 1. Route management --- */
routes: {
'': 'landing_page',
'(/)login': 'auth_redirect',
'(/)home': 'auth_redirect'
},
landing_page: function(){
this.navigate("/login", {trigger:true});
},
auth_redirect: function(){
//Checks if the user is authenticated;
//Returns either "true" or "false"
$.get('/ingeb/api_v1/auth', _.bind(function(response){
var success = $.parseJSON(response)['success'];
if (success === false){
this.renderView(Login_view);
}else if(success === true){
this.renderView(Home_view);
};
}, this));
}, ...
I would like to delegate the code that handles the authentication check and redirection to an external module. I want to do the same for helper functions that I can call as static methods (no need to instantiate) throughout the entire application.
Since my folder structure is very clean now, I would like to keep it this way.
Is there any best practice to order these:
Delegate objects;
Helper function;
in a clean folder structure ?
Here's what yeoman generated app folder hierarchy looks like
.
├── bower_components
├── images
├── scripts
│ ├── collections
│ ├── helpers
│ ├── lib
│ ├── models
│ ├── routes
│ ├── templates
│ ├── vendor
│ ├── views
│ └── main.js
└── styles
└── fonts