How can I integrate almond without changing index.html - requirejs

I have this build.js file:
({
appDir: './',
baseUrl: './js',
dir: './dist',
modules: [
{
name: 'main'
}
]
})
And in my index.html I have:
<script data-main="js/main" src="js/lib/require/require.js"></script>
When I optimize the application using:
node r.js -o build.js
All the app directory is copies into dist directory. This method is really convenient since I don't need to do any changes and I can deploy the project immediately after the optimization.
The problem is that my code uses require.js which cause overhead. How can I integrate Almond? I still with the app directory will be copied into dist directory but I don't want to edit my index.html after each optimization call.
Is there a way to integrate almond?

Related

Webpack config with React

I am creating a React application, I used npm eject so I could get to the Webpack config. I want to change the paths to assets so they don't have the leading slash. This is because when I run my application I copy the files over to a Ratpack server, so when the path is /assets/js/main.js it points to my route rather than my assets folder.
So my current webpack config is
output: {
// The build folder.
path: paths.appBuild,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'assets/static/js/[name].[chunkhash:8].js',
chunkFilename: 'assets/static/js/[name].[chunkhash:8].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: publicPath
},
However it always adds on the leading slash.
Like so
<script type="text/javascript" src="/assets/static/js/main.4d5cbecd.js">
Is there a way to have it so it builds like
<script type="text/javascript" src="assets/static/js/main.4d5cbecd.js">
Assuming you are talking about create-react-app's config, you could remove the line publicPath: publicPath, and it will generate it without leading slash.
However, I think your server should serve files too, when they are requested specifically, instead of redirecting to index page. If that's what's happening.
Another advice is for production, use production build instead of development build.

Compile Scss with Webpack

I'm still trying to wrap my head around webpack, and coming from Gulp it's quite confusing. My project structure looks like:
./root
-- src
-- styles.scss
-- bin
-- node_modules
-- webpack.config.js
So just something super simple, I want to compile the styles.scss in the src directory and output it to the bin directory. I installed the following loaders:
style-loader
css-loader
sass-loader (also installed node_sass as a dependency)
Now I know I'm not grasping something very fundamental of Webpack here but here's my webpack.config.js:
module.exports = {
entry: './src/styles.scss',
output: {
path: './bin',
filename: 'styles.css'
},
module: {
loaders: [
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}
]
}
};
When I run webpack in the root of my directory it looks like it works. But the styles.css file looks like it contains a bunch of JavaScript code. So I don't understand that and need some clarity. I'm vaguely guessing that you can't use webpack if you don't have any JavaScript files in your project (besides webpack.config.js of course...
I am by far no webpack expert, but to my understanding, this is exactly what webpack is supposed to do, according to it's own documentation:
Loaders
webpack can only process JavaScript natively, but loaders are used to
transform other resources into JavaScript. [...]
What this means is, even if you only include SCSS-Files, webpack will convert them into a JavaScript-File, which can then be included just like any other JS-File.
For example, if you changed your styles.css into styles.js, you would call it in the head of html with
<head>
...
<script type="application/javascript" src="styles.js" charset="utf-8"></script>
...
</head>
Despite this, your CSS, although called as and wrapped in JavaScript, will still be correctly treated as CSS.
Why would you want to do this?
Basically to save calls to the server.
Webpack gives you the opportunity, to bundle your JS, your [S]CSS and many other things into a single JS-File, which you will be able to fetch with a single call to the server, therefore saving lots of round-trip-times.
Still, the browser will interpret all the resources accordingly.

UnCSS setup with Brunch

Using Brunch as my build-tool for a front-end prototype, I am having difficulty setting up the UnCSS-plugin. I installed the Bootstrap 4-skeleton for a quick setup, and apart from UnCSS everything is running smoothly.
The error I get on brunch build --production is error: UnCSS: no stylesheets found. I configured the plugins like this:
plugins:
sass:
options:
includePaths: [
'bower_components/bootstrap/scss'
]
postcss:
processors: [
require('autoprefixer')
]
babel:
ignore: [
/^(bower_components|vendor)/
]
uncss:
options:
csspath: 'css/app.css'
htmlroot: 'public'
files: ['index.html']
The source files for the project are located in app: index.html in app/assets, main.scss (imports Bootstrap) and styles.css in app/stylesheets, and app.js in app/javascripts.
Brunch builds this to a folder named public, with styles in public/css/app.css and content in public/index.html. The question is, what is incorrect about the configuration of UnCSS? My understanding of it is that it works on the CSS output from the build, in which case the paths seem correct.
There is a question on SO from 2014 asking pretty much the same thing, but it was never answered.
I had not considered looking at the GitHub issues, wherein one specifically addressed this. In essence, as suggested by #1951FDG:
plugins:
uncss:
options:
ignore: [/\.\bactive\b/]
ignoreSheets: [/fonts.googleapis/]
files: ['public/index.html']
ignore: sample regex to ignore '.active' class
ignoreSheets: sample regex to ignore Google fonts
More importantly, this invocation of UnCSS reads the stylesheets linked in index.html to find the correct CSS-file, then processes it.

Can I set one config for single and multiple optimization

file structure
assets/js/
- build/
- plugin/
jquery.min.js
- src/
index.js
config.js
builds.js
require.js
assets/js/src/index.js
requirejs(['jquery']);
assets/js/config.js
requirejs.config({
baseUrl: './',
paths: {
jquery: 'plugin/jquery.min'
}
})
If I want to use r.js to optimize the file, just execute r.js -o config.js name=src/index out=build/index.js, the r.js will compile a file into build/index.js with optimization and dependency, but there will be many files need to compile in the future, so I create a builds.js
assets/js/builds.js
({
appDir: 'src',
dir: 'build',
mainConfigFile: 'config.js',
modules: [
{name: 'index'}
]
})
If I run r.js -o builds.js, I will got wrong path message.
Error: Error: ENOENT: no such file or directory, open 'D:\www\r\build\plugin\jquery.min.js'
I need to go back to config.js, and edit the path relative to src.
requirejs.config({
baseUrl: './',
paths: {
jquery: '../plugin/jquery.min'
}
})
It will work, but is it possible to write one config file for both purpose?
Specify paths again in the build file, relative to /src.
builds.js
({
appDir: 'src',
baseUrl: './',
dir: 'build',
modules: [
{name: 'index'}
],
paths: {
jquery: '../plugin/jquery.min'
}
})
The paths in the build file work differently than in the config file.
The appDir option of /src specifies that all your scripts are located in /src, however your config.js and folder structure have the /plugins outside of /src.
When the jquery path is resolved, the paths in the config.js file are used because the mainConfigFile option is used.
All module paths would need to be redefined in your build file in addition to your config file. This is because all module paths are resolved relative to the baseUrl, which is in relation to the appDir in the build file – this is the confusing bit.
Reference the following r.js example build file. https://github.com/jrburke/r.js/blob/master/build/example.build.js
The official doc on the RequireJS optimizer contains a helpful section about path resolution.
http://requirejs.org/docs/optimization.html#basics
Relative path resolution rules:
In general, if it is a path, it is relative to the build.js file used to hold the build options, or if just using command line arguments, relative to the current working directory. Example of properties that are file paths: appDir, dir, mainConfigFile, out, wrap.startFile, wrap.endFile.
For baseUrl, it is relative to appDir. If no appDir, then baseUrl is relative to the build.js file, or if just using command line arguments, the current working directory.
For paths and packages, they are relative to baseUrl, just as they are for require.js.

requirejs HTML structure

I know we could use requirejs combine files into one js file.
such like the following config.
module.exports = {
baseUrl: 'js/',
mainConfigFile: 'src/js/common.js',
dir: 'scripts/',
optimize: 'uglify2',
modules: [
{
name: 'common',
include: [
'jquery',
]
}
]
};
my result into one file is
common.js
----------------
jquery.js
modernizr.js
common.js
my question is, do we still need to put a require.js file in scripts folder and to use the following format
<script data-main="scripts/common" src="scripts/require.js"></script>
or we could just use
<script src="scripts/common.js"></script>
as files are compressed into one file?
You still need to load require.js the usual way to actually make use of the module loading benefits that it provides, and especially if you use the asynchronous functionality a lot. However, you can have a look at almond providing your code uses AMD and (from the README):
optimize all the modules into one file -- no dynamic code loading.
all modules have IDs and dependency arrays in their define() calls -- the RequireJS optimizer will take care of this for you.
only have one requirejs.config() or require.config() call.
do not use RequireJS multiversion support/contexts.
do not use require.toUrl() or require.nameToUrl().
do not use packages/packagePaths config. If you need to
use packages that have a main property,
volo can create an adapter module so
that it can work without this config. Use the amdify add command to
add the dependency to your project.
Almond is great because it doesn't need require.js at all; it wraps your own code with itself, which is a very minimal AMD loader skeleton and nowhere near as powerful as the main library. You then get a single optimised file that can be linked directly in your HTML:
<script src="scripts/common.js"></script>
The Gruntfile config for almond could look something like this:
compile: {
options: {
name: 'path/to/almond',
baseUrl: 'js',
include: ['main'],
insertRequire: ['main'],
mainConfigFile: 'scripts/config.js',
out: 'scripts/main.js',
optimizeAllPluginResources: true,
wrap: true
}
}
The above is all standard r.js boilerplate, you can find many more examples at the almond homepage.

Resources